With multiple IPC connections or outstanding totem messages, it is
possible for two threads to execute within a service engine at the same
time. Service engines are not designed to be thread safe, so this patch
locks ipc connections from occurring when service engine timers expire
or totem messages are delivered, or lib_exit_fn is called.
Regards
-teve
Index: exec/ipc.c
===================================================================
--- exec/ipc.c (revision 1846)
+++ exec/ipc.c (working copy)
@@ -104,6 +104,10 @@
static unsigned int g_gid_valid = 0;
+static void (*ipc_serialize_lock_fn) (void);
+
+static void (*ipc_serialize_unlock_fn) (void);
+
DECLARE_LIST_INIT (conn_info_list_head);
struct outq_item {
@@ -224,12 +228,14 @@
return (0);
}
+ ipc_serialize_lock_fn();
/*
* Retry library exit function if busy
*/
if (conn_info->state == CONN_STATE_THREAD_DESTROYED) {
res = ais_service[conn_info->service]->lib_exit_fn (conn_info);
if (res == -1) {
+ ipc_serialize_unlock_fn();
return (0);
} else {
conn_info->state = CONN_STATE_LIB_EXIT_CALLED;
@@ -259,6 +265,7 @@
}
close (conn_info->fd);
free (conn_info);
+ ipc_serialize_unlock_fn();
return (-1);
}
@@ -315,7 +322,9 @@
(sync_in_process() == 0)));
if (send_ok) {
+ ipc_serialize_lock_fn();
ais_service[conn_info->service]->lib_engine[header->id].lib_handler_fn (conn_info, header);
+ ipc_serialize_unlock_fn();
} else {
/*
* Overload, tell library to retry
@@ -772,12 +781,19 @@
source->conn = conn;
}
-void cs_ipc_init (unsigned int gid_valid)
+void cs_ipc_init (
+ unsigned int gid_valid,
+ void (*serialize_lock_fn) (void),
+ void (*serialize_unlock_fn) (void))
{
int libais_server_fd;
struct sockaddr_un un_addr;
int res;
+ ipc_serialize_lock_fn = serialize_lock_fn;
+
+ ipc_serialize_unlock_fn = serialize_unlock_fn;
+
/*
* Create socket for libais clients, name socket, listen for connections
*/
Index: exec/ipc.h
===================================================================
--- exec/ipc.h (revision 1846)
+++ exec/ipc.h (working copy)
@@ -40,7 +40,10 @@
extern int message_source_is_local (mar_message_source_t *source);
extern void cs_ipc_init (
- unsigned int gid_valid);
+ unsigned int gid_valid,
+ void (*serialize_lock_fn) (void),
+ void (*serialize_unlock_fn) (void)
+);
extern void *cs_conn_private_data_get (void *conn);
Index: exec/main.c
===================================================================
--- exec/main.c (revision 1846)
+++ exec/main.c (working copy)
@@ -679,7 +679,9 @@
corosync_mempool_init ();
- cs_ipc_init (main_config.gid);
+ cs_ipc_init (main_config.gid,
+ serialize_mutex_lock,
+ serialize_mutex_unlock);
/*
* Start main processing loop
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais