e_main : add hook for module load done and enlightenment info ready 36/96036/4
authorJunghwan Choi <jhhh.choi@samsung.com>
Mon, 7 Nov 2016 11:20:10 +0000 (20:20 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Tue, 8 Nov 2016 11:24:46 +0000 (03:24 -0800)
Change-Id: I7a7e513144af0ca971a8aa85db613b8a47044675
Signed-off-by: Junghwan Choi <jhhh.choi@samsung.com>
src/bin/Makefile.mk
src/bin/e_includes.h
src/bin/e_info_server.c
src/bin/e_main.c
src/bin/e_main.h [new file with mode: 0755]
src/bin/e_module.c

index 8d081f3f3045691ef4e27ad1b2b01308cd4c8d7e..62770a55ef9826c5d77235110c6b31a99e6c7d97 100644 (file)
@@ -53,6 +53,7 @@ src/bin/e_info_server.h \
 src/bin/e_init.h \
 src/bin/e_layout.h \
 src/bin/e_log.h \
+src/bin/e_main.h \
 src/bin/e_maximize.h \
 src/bin/e_module.h \
 src/bin/e_mouse.h \
index c38348e413ea162f370f96c620307534fb86de74..696b7cc66f0a8ef68317f5919103c7590ed9cc07 100644 (file)
@@ -63,3 +63,4 @@
 #include "e_process.h"
 #include "e_splitlayout.h"
 #include "e_slot.h"
+#include "e_main.h"
index b672be282370e3cab80b2ac813fea8d94f3b27c0..2db5c78a47ac4c86d98ea0bc9bce72ec0a28962c 100644 (file)
@@ -2340,6 +2340,7 @@ _e_info_server_dbus_init(void *data EINA_UNUSED)
    e_info_protocol_init();
    e_info_server_protocol_rule_path_init(getenv("E_INFO_RULE_FILE"));
    e_info_server_protocol_trace_path_init(getenv("E_INFO_TRACE_FILE"));
+   e_main_hook_call(E_MAIN_HOOK_E_INFO_READY);
 
    return ECORE_CALLBACK_CANCEL;
 
index 276d404e1602e3756cb74459776bcd7a72594bca..f0f2b9b2953417337a254551d44d21862e186bb6 100644 (file)
@@ -84,6 +84,8 @@ static void      _e_main_modules_load(Eina_Bool safe_mode);
 static Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
 static void      _e_main_create_wm_ready(void);
+static void      _e_main_hooks_clean(void);
+static void      _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED);
 
 /* local variables */
 static Eina_Bool really_know = EINA_FALSE;
@@ -98,6 +100,17 @@ static Ecore_Idle_Enterer *_idle_after = NULL;
 
 static Ecore_Event_Handler *mod_init_end = NULL;
 
+static Eina_List *hooks = NULL;
+
+static int _e_main_hooks_delete = 0;
+static int _e_main_hooks_walking = 0;
+
+static Eina_Inlist *_e_main_hooks[] =
+{
+   [E_MAIN_HOOK_MODULE_LOAD_DONE] = NULL,
+   [E_MAIN_HOOK_E_INFO_READY] = NULL
+};
+
 /* external variables */
 E_API Eina_Bool e_precache_end = EINA_FALSE;
 E_API Eina_Bool x_fatal = EINA_FALSE;
@@ -745,6 +758,8 @@ _e_main_shutdown(int errcode)
 
    printf("E: Begin Shutdown Procedure!\n");
 
+   E_FREE_LIST(hooks, e_main_hook_del);
+
    if (_idle_before) ecore_idle_enterer_del(_idle_before);
    _idle_before = NULL;
    if (_idle_after) ecore_idle_enterer_del(_idle_after);
@@ -1274,3 +1289,74 @@ _e_main_create_wm_ready(void)
         PRCTL("[Winsys] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
      }
 }
+
+static void
+_e_main_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Main_Hook *mh;
+   unsigned int x;
+
+   for (x = 0; x < E_MAIN_HOOK_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_main_hooks[x], l, mh)
+       {
+          if (!mh->delete_me) continue;
+          _e_main_hooks[x] = eina_inlist_remove(_e_main_hooks[x],
+                                                EINA_INLIST_GET(mh));
+          free(mh);
+       }
+}
+
+static void
+_e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED)
+{
+   E_Main_Hook *mh;
+
+   _e_main_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_main_hooks[hookpoint], mh)
+     {
+        if (mh->delete_me) continue;
+        mh->func(mh->data);
+     }
+   _e_main_hooks_walking--;
+   if ((_e_main_hooks_walking == 0) && (_e_main_hooks_delete > 0))
+     _e_main_hooks_clean();
+}
+
+E_API E_Main_Hook *
+e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data)
+{
+   E_Main_Hook *mh;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_MAIN_HOOK_LAST, NULL);
+   mh = E_NEW(E_Main_Hook, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(mh, NULL);
+   mh->hookpoint = hookpoint;
+   mh->func = func;
+   mh->data = (void*)data;
+   _e_main_hooks[hookpoint] = eina_inlist_append(_e_main_hooks[hookpoint],
+                                                 EINA_INLIST_GET(mh));
+   return mh;
+}
+
+E_API void
+e_main_hook_del(E_Main_Hook *mh)
+{
+   mh->delete_me = 1;
+   if (_e_main_hooks_walking == 0)
+     {
+        _e_main_hooks[mh->hookpoint] = eina_inlist_remove(_e_main_hooks[mh->hookpoint],
+                                                          EINA_INLIST_GET(mh));
+        free(mh);
+     }
+   else
+     _e_main_hooks_delete++;
+}
+
+E_API void
+e_main_hook_call(E_Main_Hook_Point hookpoint)
+{
+   if ((hookpoint < 0) || (hookpoint >= E_MAIN_HOOK_LAST)) return;
+
+   _e_main_hook_call(hookpoint, NULL);
+}
diff --git a/src/bin/e_main.h b/src/bin/e_main.h
new file mode 100755 (executable)
index 0000000..c590874
--- /dev/null
@@ -0,0 +1,31 @@
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_MAIN_H
+#define E_MAIN_H
+
+typedef struct _E_Main_Hook E_Main_Hook;
+
+typedef enum _E_Main_Hook_Point
+{
+   E_MAIN_HOOK_MODULE_LOAD_DONE,
+   E_MAIN_HOOK_E_INFO_READY,
+   E_MAIN_HOOK_LAST
+} E_Main_Hook_Point;
+
+typedef void (*E_Main_Hook_Cb)(void *data);
+
+struct _E_Main_Hook
+{
+   EINA_INLIST;
+   E_Main_Hook_Point hookpoint;
+   E_Main_Hook_Cb    func;
+   void             *data;
+   unsigned char     delete_me : 1;
+};
+
+E_API E_Main_Hook *e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data);
+E_API void e_main_hook_del(E_Main_Hook *ph);
+
+E_API void e_main_hook_call(E_Main_Hook_Point hookpoint);
+#endif
+#endif
index a45f6e86c02d48ef9d53b45d81b67282506b74e6..ef075b625277dc1704dafddd057b7296bd14c510 100644 (file)
@@ -298,6 +298,8 @@ e_module_all_load(void)
         _e_modules_initting = EINA_FALSE;
      }
 
+   e_main_hook_call(E_MAIN_HOOK_MODULE_LOAD_DONE);
+
    unsetenv("E_MODULE_LOAD");
 
    TRACE_DS_END();