Attached is another IPC patch (apply to current trunk). It need some
cleanups, variable names modification (comments welcomed), little more
testing (looks very stable) and split to 2-3 patches, but finally should
solve all issues and cyclic requirements.

Regards,
  Honza
diff --git a/trunk/exec/apidef.c b/trunk/exec/apidef.c
index 5e1f178..adb2c88 100644
--- a/trunk/exec/apidef.c
+++ b/trunk/exec/apidef.c
@@ -129,6 +129,7 @@ static struct corosync_api_v1 apidef_corosync_api_v1 = {
        .tpg_groups_reserve = NULL,
        .tpg_groups_release = NULL,
        .schedwrk_create = schedwrk_create,
+       .schedwrk_create_nolock = schedwrk_create_nolock,
        .schedwrk_destroy = schedwrk_destroy,
        .sync_request = NULL, //sync_request,
        .quorum_is_quorate = corosync_quorum_is_quorate,
diff --git a/trunk/exec/coroipcs.c b/trunk/exec/coroipcs.c
index a0ef133..9f63c69 100644
--- a/trunk/exec/coroipcs.c
+++ b/trunk/exec/coroipcs.c
@@ -75,6 +75,7 @@
 #include <corosync/hdb.h>
 #include <corosync/coroipcs.h>
 #include <corosync/coroipc_ipc.h>
+#include <corosync/totem/coropoll.h>
 
 #define LOGSYS_UTILS_ONLY 1
 #include <corosync/engine/logsys.h>
@@ -1043,41 +1044,26 @@ static void _corosync_ipc_init(void)
        api->poll_accept_add (server_fd);
 }
 
-void coroipcs_ipc_exit (void)
+void coroipcs_ipc_service_exit (unsigned int service, hdb_handle_t poll_handle)
 {
-       struct list_head *list;
+       struct list_head *list, *list_next;
        struct conn_info *conn_info;
-       unsigned int res;
+       //unsigned int res;
 
        for (list = conn_info_list_head.next; list != &conn_info_list_head;
-               list = list->next) {
+               list = list_next) {
+
+               list_next = list->next;
 
                conn_info = list_entry (list, struct conn_info, list);
 
-               if (conn_info->state != CONN_STATE_THREAD_ACTIVE)
+               if (conn_info->service != service || conn_info->state != 
CONN_STATE_THREAD_ACTIVE)
                        continue;
 
                ipc_disconnect (conn_info);
-
-#if _POSIX_THREAD_PROCESS_SHARED > 0
-               sem_destroy (&conn_info->control_buffer->sem0);
-               sem_destroy (&conn_info->control_buffer->sem1);
-               sem_destroy (&conn_info->control_buffer->sem2);
-#else
-               semctl (conn_info->semid, 0, IPC_RMID);
-#endif
-
-               /*
-                * Unmap memory segments
-                */
-               res = munmap ((void *)conn_info->control_buffer,
-                       conn_info->control_size);
-               res = munmap ((void *)conn_info->request_buffer,
-                       conn_info->request_size);
-               res = munmap ((void *)conn_info->response_buffer,
-                       conn_info->response_size);
-               res = circular_memory_unmap (conn_info->dispatch_buffer,
-                       conn_info->dispatch_size);
+               poll_dispatch_delete (poll_handle, conn_info->fd);
+               while (conn_info_destroy (conn_info) != -1)
+                       ;
        }
 }
 
diff --git a/trunk/exec/main.c b/trunk/exec/main.c
index b2b84d2..0944b00 100644
--- a/trunk/exec/main.c
+++ b/trunk/exec/main.c
@@ -156,8 +156,7 @@ void corosync_state_dump (void)
 
 static void unlink_all_completed (void)
 {
-       poll_stop (0);
-       coroipcs_ipc_exit ();
+       poll_stop (corosync_poll_handle);
        totempg_finalize ();
 
        corosync_exit_error (AIS_DONE_EXIT);
@@ -180,7 +179,7 @@ static void *corosync_exit_thread_handler (void *arg)
 {
        sem_wait (&corosync_exit_sem);
 
-       corosync_service_unlink_all (api, unlink_all_completed);
+       corosync_service_unlink_all (api, unlink_all_completed, 
corosync_poll_handle);
 
        return arg;
 }
diff --git a/trunk/exec/mainconfig.c b/trunk/exec/mainconfig.c
index c35ba72..99dc952 100644
--- a/trunk/exec/mainconfig.c
+++ b/trunk/exec/mainconfig.c
@@ -277,6 +277,8 @@ static int corosync_main_config_log_destination_set (
                         objdb_key, replacement);
                }
 
+               mode = logsys_config_mode_get (subsys);
+
                if (strcmp (value, "yes") == 0) {
                        mode |= mode_mask;
                        if (logsys_config_mode_set(subsys, mode) < 0) {
diff --git a/trunk/exec/schedwrk.c b/trunk/exec/schedwrk.c
index 0c330e9..4cfa38f 100644
--- a/trunk/exec/schedwrk.c
+++ b/trunk/exec/schedwrk.c
@@ -46,6 +46,7 @@ struct schedwrk_instance {
        int (*schedwrk_fn) (const void *);
        const void *context;
        void *callback_handle;
+       int lock;
 };
 
 union u {
@@ -70,9 +71,13 @@ static int schedwrk_do (enum totem_callback_token_type type, 
const void *context
                goto error_exit;
        }
 
-       serialize_lock ();
+       if (instance->lock)
+               serialize_lock ();
+
        res = instance->schedwrk_fn (instance->context);
-       serialize_unlock ();
+
+       if (instance->lock)
+               serialize_unlock ();
 
        if (res == 0) {
                hdb_handle_destroy (&schedwrk_instance_database, 
hdb_nocheck_convert (handle));
@@ -93,10 +98,11 @@ void schedwrk_init (
        serialize_unlock = serialize_unlock_fn;
 }
 
-int schedwrk_create (
+static int schedwrk_create_lock (
        hdb_handle_t *handle,
        int (schedwrk_fn) (const void *),
-       const void *context)
+       const void *context,
+       int lock)
 {
        struct schedwrk_instance *instance;
        int res;
@@ -121,6 +127,7 @@ int schedwrk_create (
 
        instance->schedwrk_fn = schedwrk_fn;
        instance->context = context;
+       instance->lock = lock;
 
         hdb_handle_put (&schedwrk_instance_database, *handle);
 
@@ -133,6 +140,22 @@ error_exit:
        return (-1);
 }
 
+int schedwrk_create (
+       hdb_handle_t *handle,
+       int (schedwrk_fn) (const void *),
+       const void *context)
+{
+       return schedwrk_create_lock (handle, schedwrk_fn, context, 1);
+}
+
+int schedwrk_create_nolock (
+       hdb_handle_t *handle,
+       int (schedwrk_fn) (const void *),
+       const void *context)
+{
+       return schedwrk_create_lock (handle, schedwrk_fn, context, 0);
+}
+
 void schedwrk_destroy (hdb_handle_t handle)
 {
        hdb_handle_destroy (&schedwrk_instance_database, handle);
diff --git a/trunk/exec/schedwrk.h b/trunk/exec/schedwrk.h
index e67215b..29d6409 100644
--- a/trunk/exec/schedwrk.h
+++ b/trunk/exec/schedwrk.h
@@ -43,6 +43,11 @@ int schedwrk_create (
         int (schedwrk_fn) (const void *),
         const void *context);
 
+int schedwrk_create_nolock (
+        hdb_handle_t *handle,
+        int (schedwrk_fn) (const void *),
+        const void *context);
+
 void schedwrk_destroy (hdb_handle_t handle);
 
 #endif /* SCHEDWRK_H_DEFINED */
diff --git a/trunk/exec/service.c b/trunk/exec/service.c
index d99e7bf..12b4034 100644
--- a/trunk/exec/service.c
+++ b/trunk/exec/service.c
@@ -55,6 +55,8 @@
 #include <corosync/engine/coroapi.h>
 #include "service.h"
 
+#include <corosync/coroipcs.h>
+
 LOGSYS_DECLARE_SUBSYS ("SERV");
 
 struct default_service {
@@ -99,8 +101,11 @@ static hdb_handle_t object_stats_services_handle;
 
 static void (*service_unlink_all_complete) (void) = NULL;
 
-static hdb_handle_t unlink_all_handle;
-
+static hdb_handle_t swrk_service_exit_handle;
+static hdb_handle_t swrk_service_unlink_handle;
+static hdb_handle_t unlink_service_handle;
+static int unlink_service_engine;
+static hdb_handle_t coropoll_handle;
 
 static unsigned int default_services_requested (struct corosync_api_v1 
*corosync_api)
 {
@@ -272,7 +277,8 @@ corosync_service_unlink_priority (
        struct corosync_api_v1 *corosync_api,
        int lowest_priority,
        int *current_priority,
-       int *current_service_engine)
+       int *current_service_engine,
+       hdb_handle_t *current_service_handle)
 {
        unsigned short *service_id;
        hdb_handle_t object_service_handle;
@@ -319,11 +325,6 @@ corosync_service_unlink_priority (
                                                        return (-1);
                                                }
                                        }
-                                       log_printf(LOGSYS_LEVEL_NOTICE,
-                                               "Service engine unloaded: %s\n",
-                                                  
ais_service[*current_service_engine]->name);
-
-                                       ais_service[*current_service_engine] = 
NULL;
 
                                        res = corosync_api->object_key_get (
                                                object_service_handle,
@@ -331,17 +332,24 @@ corosync_service_unlink_priority (
                                                (void *)&found_service_handle,
                                                NULL);
 
-                                       lcr_ifact_release 
(*found_service_handle);
+                                       *current_service_handle = 
*found_service_handle;
 
-                                       corosync_api->object_destroy 
(object_service_handle);
-                                       break;
+                                       corosync_api->object_find_destroy 
(object_find_handle);
+
+                                       /*
+                                        * Call this again
+                                        */
+                                       return (1);
                                }
                        }
 
                        corosync_api->object_find_destroy (object_find_handle);
                }
        }
-       return 0;
+       /*
+        * We finish unlink of all services
+        */
+       return (0);
 }
 
 static unsigned int service_unlink_and_exit (
@@ -431,6 +439,11 @@ static unsigned int service_unlink_and_exit (
                                }
                        }
 
+                       /*
+                        * Exit all ipc connections dependand on this service
+                        */
+                       coroipcs_ipc_service_exit (*service_id, 
coropoll_handle);
+
                        log_printf(LOGSYS_LEVEL_NOTICE,
                                "Service engine unloaded: %s\n",
                                   ais_service[*service_id]->name);
@@ -538,12 +551,39 @@ unsigned int corosync_service_defaults_link_and_init 
(struct corosync_api_v1 *co
        return (0);
 }
 
-static int unlink_all_schedwrk_handler (const void *data) {
+static int service_exit_schedwrk_handler (const void *data);
+
+static int service_unlink_schedwrk_handler (const void *data) {
+       struct corosync_api_v1 *api = (struct corosync_api_v1 *)data;
+
+       /*
+        * Exit all ipc connections dependand on this service
+        */
+       coroipcs_ipc_service_exit (unlink_service_engine, coropoll_handle);
+
+       log_printf(LOGSYS_LEVEL_NOTICE,
+               "Service engine unloaded: %s\n",
+               ais_service[unlink_service_engine]->name);
+
+       ais_service[unlink_service_engine] = NULL;
+
+       lcr_ifact_release (unlink_service_handle);
+
+       api->schedwrk_create (
+               &swrk_service_exit_handle,
+               &service_exit_schedwrk_handler,
+               api);
+
+       return 0;
+}
+
+static int service_exit_schedwrk_handler (const void *data) {
        int res;
        static int current_priority = 0;
        static int current_service_engine = 0;
        static int called = 0;
        struct corosync_api_v1 *api = (struct corosync_api_v1 *)data;
+       hdb_handle_t service_handle;
 
        if (called == 0) {
                log_printf(LOGSYS_LEVEL_NOTICE,
@@ -556,16 +596,31 @@ static int unlink_all_schedwrk_handler (const void *data) 
{
                api,
                0,
                &current_priority,
-               &current_service_engine);
+               &current_service_engine,
+               &service_handle);
        if (res == 0) {
                service_unlink_all_complete();
+               return (res);
+       }
+
+       if (res == 1) {
+               unlink_service_engine = current_service_engine;
+               unlink_service_handle = service_handle;
+
+               api->schedwrk_create_nolock (
+                       &swrk_service_unlink_handle,
+                       &service_unlink_schedwrk_handler,
+                       api);
+               return (0);
        }
+
        return (res);
 }
                
 void corosync_service_unlink_all (
        struct corosync_api_v1 *api,
-       void (*unlink_all_complete) (void))
+       void (*unlink_all_complete) (void),
+       hdb_handle_t poll_handle)
 {
        static int called = 0;
 
@@ -579,10 +634,12 @@ void corosync_service_unlink_all (
        if (called == 0) {
                called = 1;
        }
-       
+
+       coropoll_handle = poll_handle;
+
        api->schedwrk_create (
-               &unlink_all_handle,
-               &unlink_all_schedwrk_handler,
+               &swrk_service_exit_handle,
+               &service_exit_schedwrk_handler,
                api);
 }
 
diff --git a/trunk/exec/service.h b/trunk/exec/service.h
index efb3e44..1228bd0 100644
--- a/trunk/exec/service.h
+++ b/trunk/exec/service.h
@@ -59,7 +59,8 @@ extern unsigned int corosync_service_unlink_and_exit (
  */
 extern void corosync_service_unlink_all (
         struct corosync_api_v1 *api,
-        void (*unlink_all_complete) (void));
+        void (*unlink_all_complete) (void),
+       hdb_handle_t poll_handle);
 
 /*
  * Load all of the default services
diff --git a/trunk/include/corosync/coroipcs.h 
b/trunk/include/corosync/coroipcs.h
index 3838af8..614037e 100644
--- a/trunk/include/corosync/coroipcs.h
+++ b/trunk/include/corosync/coroipcs.h
@@ -150,7 +150,7 @@ extern void coroipcs_refcount_inc (void *conn);
 
 extern void coroipcs_refcount_dec (void *conn);
 
-extern void coroipcs_ipc_exit (void);
+extern void coroipcs_ipc_service_exit (unsigned int service, hdb_handle_t 
poll_handle);
 
 extern int coroipcs_handler_accept (
        int fd,
diff --git a/trunk/include/corosync/engine/coroapi.h 
b/trunk/include/corosync/engine/coroapi.h
index 0c487ca..556a568 100644
--- a/trunk/include/corosync/engine/coroapi.h
+++ b/trunk/include/corosync/engine/coroapi.h
@@ -627,6 +627,11 @@ struct corosync_api_v1 {
                objdb_value_types_t *type);
 
        void *(*totem_get_stats)(void);
+
+       int (*schedwrk_create_nolock) (
+               hdb_handle_t *handle,
+               int (schedwrk_fn) (const void *),
+               const void *context);
 };
 
 #define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) )
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to