take 2 :(
On Fri, 2009-03-13 at 03:00 -0700, Steven Dake wrote:
> 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;
@@ -239,6 +245,7 @@
pthread_mutex_lock (&conn_info->mutex);
if (conn_info->refcount > 0) {
pthread_mutex_unlock (&conn_info->mutex);
+ ipc_serialize_unlock_fn();
return (0);
}
list_del (&conn_info->list);
@@ -259,6 +266,7 @@
}
close (conn_info->fd);
free (conn_info);
+ ipc_serialize_unlock_fn();
return (-1);
}
@@ -315,7 +323,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 +782,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