summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2018-02-02 16:59:56 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2018-02-02 16:59:44 -0500
commit95a339733a6b296d445fa4cb03f6f88b12f415a7 (patch)
treefd00cac96cea283301782f354bfe525952d616d7
parent10ce0cbd8ac8d176a13d9be2e9e53a56a2a616ac (diff)
eldbus: make connections fork-safe
after a fork, any existing connection objects can no longer be used, but it's up to the user to destroy them. internally, this prevents existing connections from ever being returned as valid connections and creates new ones after a fork also destroy fd handlers for connections to ensure that no data is accidentally clobbered before the connections are cleaned up
-rw-r--r--src/lib/eldbus/eldbus_core.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/src/lib/eldbus/eldbus_core.c b/src/lib/eldbus/eldbus_core.c
index 91a4021010..ba4a3ba684 100644
--- a/src/lib/eldbus/eldbus_core.c
+++ b/src/lib/eldbus/eldbus_core.c
@@ -85,6 +85,45 @@ static void _eldbus_connection_context_event_cb_del(Eldbus_Connection_Context_Ev
85static void eldbus_dispatch_name_owner_change(Eldbus_Connection_Name *cn, const char *old_id); 85static void eldbus_dispatch_name_owner_change(Eldbus_Connection_Name *cn, const char *old_id);
86static void _eldbus_connection_free(Eldbus_Connection *conn); 86static void _eldbus_connection_free(Eldbus_Connection *conn);
87 87
88static void
89eldbus_fd_handler_del(Eldbus_Handler_Data *hd)
90{
91 if (!hd->fd_handler) return;
92
93 DBG("free Eldbus_Handler_Data %d", hd->fd);
94 hd->conn->fd_handlers = eina_inlist_remove(hd->conn->fd_handlers,
95 EINA_INLIST_GET(hd));
96 if (hd->fd_handler)
97 {
98 ecore_main_fd_handler_del(hd->fd_handler);
99 hd->fd_handler = NULL;
100 }
101
102 free(hd);
103}
104
105static void
106_eldbus_fork_reset()
107{
108 int i;
109
110 for (i =0; i < ELDBUS_CONNECTION_TYPE_LAST - 1; i++)
111 {
112 Eldbus_Connection *conn = shared_connections[i];
113 if (conn)
114 {
115 Eina_Inlist *list;
116 Eldbus_Handler_Data *fd_handler;
117
118 EINA_INLIST_FOREACH_SAFE(conn->fd_handlers, list, fd_handler)
119 dbus_watch_set_data(fd_handler->watch, NULL, NULL);
120 }
121 shared_connections[i] = NULL;
122 }
123 if (address_connections) eina_hash_free(address_connections);
124 address_connections = NULL;
125}
126
88EAPI int 127EAPI int
89eldbus_init(void) 128eldbus_init(void)
90{ 129{
@@ -131,7 +170,7 @@ eldbus_init(void)
131 if (!eldbus_object_init()) goto object_failed; 170 if (!eldbus_object_init()) goto object_failed;
132 if (!eldbus_proxy_init()) goto proxy_failed; 171 if (!eldbus_proxy_init()) goto proxy_failed;
133 if (!eldbus_service_init()) goto service_failed; 172 if (!eldbus_service_init()) goto service_failed;
134 173 ecore_fork_reset_callback_add(_eldbus_fork_reset, NULL);
135 return _eldbus_init_count; 174 return _eldbus_init_count;
136 175
137service_failed: 176service_failed:
@@ -205,6 +244,7 @@ eldbus_shutdown(void)
205 if (--_eldbus_init_count) 244 if (--_eldbus_init_count)
206 return _eldbus_init_count; 245 return _eldbus_init_count;
207 246
247 ecore_fork_reset_callback_del(_eldbus_fork_reset, NULL);
208 if (shared_connections[ELDBUS_CONNECTION_TYPE_SESSION - 1]) 248 if (shared_connections[ELDBUS_CONNECTION_TYPE_SESSION - 1])
209 { 249 {
210 CRI("Alive TYPE_SESSION connection"); 250 CRI("Alive TYPE_SESSION connection");
@@ -548,24 +588,6 @@ eldbus_connection_name_object_get(Eldbus_Connection *conn, const char *name, con
548 return eina_hash_find(cn->objects, path); 588 return eina_hash_find(cn->objects, path);
549} 589}
550 590
551
552static void
553eldbus_fd_handler_del(Eldbus_Handler_Data *hd)
554{
555 if (!hd->fd_handler) return;
556
557 DBG("free Eldbus_Handler_Data %d", hd->fd);
558 hd->conn->fd_handlers = eina_inlist_remove(hd->conn->fd_handlers,
559 EINA_INLIST_GET(hd));
560 if (hd->fd_handler)
561 {
562 ecore_main_fd_handler_del(hd->fd_handler);
563 hd->fd_handler = NULL;
564 }
565
566 free(hd);
567}
568
569static Eina_Bool 591static Eina_Bool
570eldbus_fd_handler(void *data, Ecore_Fd_Handler *fd_handler) 592eldbus_fd_handler(void *data, Ecore_Fd_Handler *fd_handler)
571{ 593{
@@ -1256,7 +1278,10 @@ _eldbus_connection_free(Eldbus_Connection *conn)
1256 if (conn->type && conn->shared) 1278 if (conn->type && conn->shared)
1257 { 1279 {
1258 if (conn->type == ELDBUS_CONNECTION_TYPE_ADDRESS) 1280 if (conn->type == ELDBUS_CONNECTION_TYPE_ADDRESS)
1259 eina_hash_del_by_data(address_connections, conn); 1281 {
1282 if (address_connections)
1283 eina_hash_del_by_data(address_connections, conn);
1284 }
1260 else if (shared_connections[conn->type - 1] == (void *) conn) 1285 else if (shared_connections[conn->type - 1] == (void *) conn)
1261 shared_connections[conn->type - 1] = NULL; 1286 shared_connections[conn->type - 1] = NULL;
1262 } 1287 }