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

Reply via email to