summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-06-24 19:24:21 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-06-24 19:28:17 +0900
commit5abfefe99ea290191ef59f840b11c64fb9792edb (patch)
treef156bef3d97b775df535604fba800fa7f2d2cf2e /src/bin
parentc6011926bad960136af132a97b54cb38199638fe (diff)
efl - efreetd service move from dbus session bus to ecore ipc
this fixes warnings about no efreet dbus session bus in non session environments as brought up on the mailing lists with: Subject: Re: [E-devel] [EGIT] [core/efl] master 01/01: edje: unset efreet cache update flag to prevent dbus connections this moves all of efreetd client and server to ecore ipc, with client auto-launching efreetd if not found as a service and trying for up to 500ms to connect. efreetd times out on last connection or no connections after 10sec so it wont hang around forever if not in use. it seems to work in my testing, so let me know if there is an issue. @fix
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/efreet/efreetd.c10
-rw-r--r--src/bin/efreet/efreetd_cache.c2
-rw-r--r--src/bin/efreet/efreetd_dbus.c262
-rw-r--r--src/bin/efreet/efreetd_ipc.c226
-rw-r--r--src/bin/efreet/efreetd_ipc.h (renamed from src/bin/efreet/efreetd_dbus.h)8
5 files changed, 236 insertions, 272 deletions
diff --git a/src/bin/efreet/efreetd.c b/src/bin/efreet/efreetd.c
index 1661ec293b..ffb15a09c3 100644
--- a/src/bin/efreet/efreetd.c
+++ b/src/bin/efreet/efreetd.c
@@ -12,8 +12,8 @@
12#include <Ecore_File.h> 12#include <Ecore_File.h>
13 13
14#include "efreetd.h" 14#include "efreetd.h"
15#include "efreetd_dbus.h"
16#include "efreetd_cache.h" 15#include "efreetd_cache.h"
16#include "efreetd_ipc.h"
17 17
18int efreetd_log_dom = -1; 18int efreetd_log_dom = -1;
19 19
@@ -61,13 +61,13 @@ main(int argc, char *argv[])
61 if (!ecore_init()) goto ecore_error; 61 if (!ecore_init()) goto ecore_error;
62 ecore_app_args_set(argc, (const char **)argv); 62 ecore_app_args_set(argc, (const char **)argv);
63 if (!ecore_file_init()) goto ecore_file_error; 63 if (!ecore_file_init()) goto ecore_file_error;
64 if (!dbus_init()) goto dbus_error; 64 if (!ipc_init()) goto ipc_error;
65 if (!cache_init()) goto cache_error; 65 if (!cache_init()) goto cache_error;
66 66
67 ecore_main_loop_begin(); 67 ecore_main_loop_begin();
68 68
69 cache_shutdown(); 69 cache_shutdown();
70 dbus_shutdown(); 70 ipc_shutdown();
71 ecore_file_shutdown(); 71 ecore_file_shutdown();
72 ecore_shutdown(); 72 ecore_shutdown();
73 eina_log_domain_unregister(efreetd_log_dom); 73 eina_log_domain_unregister(efreetd_log_dom);
@@ -76,8 +76,8 @@ main(int argc, char *argv[])
76 return 0; 76 return 0;
77 77
78cache_error: 78cache_error:
79 dbus_shutdown(); 79 ipc_shutdown();
80dbus_error: 80ipc_error:
81 ecore_file_shutdown(); 81 ecore_file_shutdown();
82ecore_file_error: 82ecore_file_error:
83 ecore_shutdown(); 83 ecore_shutdown();
diff --git a/src/bin/efreet/efreetd_cache.c b/src/bin/efreet/efreetd_cache.c
index a4887e6841..a2ef783db8 100644
--- a/src/bin/efreet/efreetd_cache.c
+++ b/src/bin/efreet/efreetd_cache.c
@@ -7,7 +7,7 @@
7#include <Ecore_File.h> 7#include <Ecore_File.h>
8#include <Eet.h> 8#include <Eet.h>
9#include "efreetd.h" 9#include "efreetd.h"
10#include "efreetd_dbus.h" 10#include "efreetd_ipc.h"
11 11
12#include "Efreet.h" 12#include "Efreet.h"
13#define EFREET_MODULE_LOG_DOM efreetd_log_dom 13#define EFREET_MODULE_LOG_DOM efreetd_log_dom
diff --git a/src/bin/efreet/efreetd_dbus.c b/src/bin/efreet/efreetd_dbus.c
deleted file mode 100644
index 82a66c179f..0000000000
--- a/src/bin/efreet/efreetd_dbus.c
+++ /dev/null
@@ -1,262 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6#include <Eldbus.h>
7
8#include "efreetd.h"
9#include "efreetd_cache.h"
10
11#define BUS "org.enlightenment.Efreet"
12#define PATH "/org/enlightenment/Efreet"
13#define INTERFACE "org.enlightenment.Efreet"
14
15/* internal */
16enum
17{
18 EFREET_SIGNAL_ICON_CACHE_UPDATE = 0,
19 EFREET_SIGNAL_DESKTOP_CACHE_UPDATE
20};
21
22static Eldbus_Connection *conn;
23static Eldbus_Service_Interface *iface;
24
25static Ecore_Timer *_shutdown = NULL;
26static int clients = 0;
27
28static Eina_Bool
29do_shutdown(void *data EINA_UNUSED)
30{
31 quit();
32 return ECORE_CALLBACK_CANCEL;
33}
34
35static void
36disconnected(void *context EINA_UNUSED, Eldbus_Connection *connection EINA_UNUSED, void *event_info EINA_UNUSED)
37{
38 INF("disconnected");
39 quit();
40}
41
42static void
43client_name_owner_changed_cb(void *data EINA_UNUSED, const char *bus, const char *old_id EINA_UNUSED, const char *new_id)
44{
45 if (new_id[0])
46 return;
47 eldbus_name_owner_changed_callback_del(conn, bus,
48 client_name_owner_changed_cb, NULL);
49 clients--;
50 if (clients <= 0)
51 {
52 clients = 0;
53 if (_shutdown) ecore_timer_del(_shutdown);
54 _shutdown = ecore_timer_add(10.0, do_shutdown, NULL);
55 }
56}
57
58static Eldbus_Message *
59do_register(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
60{
61 Eldbus_Message *reply;
62 const char *lang;
63
64 if (!eldbus_message_arguments_get(message, "s", &lang))
65 {
66 ERR("Error getting arguments.");
67 return NULL;
68 }
69 setenv("LANG", lang, 1);
70
71 clients++;
72 if (_shutdown) ecore_timer_del(_shutdown);
73 _shutdown = NULL;
74
75 eldbus_name_owner_changed_callback_add(conn,
76 eldbus_message_sender_get(message),
77 client_name_owner_changed_cb, NULL,
78 EINA_FALSE);
79 reply = eldbus_message_method_return_new(message);
80 eldbus_message_arguments_append(reply, "b", cache_desktop_exists());
81 return reply;
82}
83
84static Eldbus_Message *
85add_desktop_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
86{
87 Eldbus_Message_Iter *array = NULL;
88 const char *dir;
89
90 if (!eldbus_message_arguments_get(message, "as", &array))
91 {
92 ERR("Error getting arguments.");
93 return NULL;
94 }
95
96 while (eldbus_message_iter_get_and_next(array, 's', &dir))
97 {
98 cache_desktop_dir_add(dir);
99 }
100
101 return NULL;
102}
103
104static Eldbus_Message *
105add_icon_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
106{
107 Eldbus_Message_Iter *array = NULL;
108 const char *dir;
109
110 if (!eldbus_message_arguments_get(message, "as", &array))
111 {
112 ERR("Error getting arguments.");
113 return NULL;
114 }
115
116 while (eldbus_message_iter_get_and_next(array, 's', &dir))
117 {
118 cache_icon_dir_add(dir);
119 }
120
121 return NULL;
122}
123
124static Eldbus_Message *
125build_desktop_cache(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message EINA_UNUSED)
126{
127 const char *lang;
128
129 if (!eldbus_message_arguments_get(message, "s", &lang))
130 {
131 ERR("Error getting arguments.");
132 return NULL;
133 }
134 setenv("LANG", lang, 1);
135
136 cache_desktop_update();
137 return NULL;
138}
139
140static Eldbus_Message *
141add_icon_exts(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message)
142{
143 Eldbus_Message_Iter *array = NULL;
144 const char *ext;
145
146 if (!eldbus_message_arguments_get(message, "as", &array))
147 {
148 ERR("Error getting arguments.");
149 return NULL;
150 }
151
152 while (eldbus_message_iter_get_and_next(array, 's', &ext))
153 {
154 cache_icon_ext_add(ext);
155 }
156
157 return NULL;
158}
159
160static const Eldbus_Signal signals[] = {
161 [EFREET_SIGNAL_ICON_CACHE_UPDATE] = {"IconCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0},
162 [EFREET_SIGNAL_DESKTOP_CACHE_UPDATE] = {"DesktopCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0},
163 { NULL, NULL, 0 }
164};
165
166static const Eldbus_Method methods[] = {
167 {
168 "Register", ELDBUS_ARGS({"s", "lang info"}), ELDBUS_ARGS({"b", "cache exists"}),
169 do_register, 0
170 },
171 {
172 "AddDesktopDirs", ELDBUS_ARGS({"as", "dirs"}), NULL,
173 add_desktop_dirs, ELDBUS_METHOD_FLAG_NOREPLY
174 },
175 {
176 "BuildDesktopCache", ELDBUS_ARGS({"s", "lang info"}), NULL,
177 build_desktop_cache, ELDBUS_METHOD_FLAG_NOREPLY
178 },
179 {
180 "AddIconDirs", ELDBUS_ARGS({"as", "dirs"}), NULL,
181 add_icon_dirs, ELDBUS_METHOD_FLAG_NOREPLY
182 },
183 {
184 "AddIconExts", ELDBUS_ARGS({"as", "exts"}), NULL,
185 add_icon_exts, ELDBUS_METHOD_FLAG_NOREPLY
186 },
187 { NULL, NULL, NULL, NULL, 0 }
188};
189
190static const Eldbus_Service_Interface_Desc desc = {
191 INTERFACE, methods, signals, NULL, NULL, NULL
192};
193
194static void
195on_name_request(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
196{
197 unsigned int reply;
198
199 if (eldbus_message_error_get(msg, NULL, NULL))
200 {
201 ERR("error on on_name_request");
202 quit();
203 return;
204 }
205
206 if (!eldbus_message_arguments_get(msg, "u", &reply))
207 {
208 ERR("error getting arguments on on_name_request");
209 quit();
210 return;
211 }
212
213 if (reply != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
214 {
215 ERR("error name already in use");
216 quit();
217 return;
218 }
219 INF("name requested");
220}
221
222/* external */
223void
224send_signal_icon_cache_update(Eina_Bool update)
225{
226 eldbus_service_signal_emit(iface, EFREET_SIGNAL_ICON_CACHE_UPDATE, update);
227}
228
229void
230send_signal_desktop_cache_update(Eina_Bool update)
231{
232 eldbus_service_signal_emit(iface, EFREET_SIGNAL_DESKTOP_CACHE_UPDATE, update);
233}
234
235Eina_Bool
236dbus_init(void)
237{
238 if (!eldbus_init()) return EINA_FALSE;
239
240 conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
241 if (!conn) goto conn_error;
242
243 eldbus_connection_event_callback_add(conn,
244 ELDBUS_CONNECTION_EVENT_DISCONNECTED, disconnected, NULL);
245 iface = eldbus_service_interface_register(conn, PATH, &desc);
246 eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
247 on_name_request, NULL);
248
249 return EINA_TRUE;
250conn_error:
251 eldbus_shutdown();
252 return EINA_FALSE;
253}
254
255Eina_Bool
256dbus_shutdown(void)
257{
258 eldbus_connection_unref(conn);
259 eldbus_shutdown();
260 return EINA_TRUE;
261
262}
diff --git a/src/bin/efreet/efreetd_ipc.c b/src/bin/efreet/efreetd_ipc.c
new file mode 100644
index 0000000000..7b918d4713
--- /dev/null
+++ b/src/bin/efreet/efreetd_ipc.c
@@ -0,0 +1,226 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6#include <Ecore_Ipc.h>
7
8#include "efreetd.h"
9#include "efreetd_cache.h"
10
11static int init = 0;
12static Ecore_Ipc_Server *ipc = NULL;
13static Ecore_Event_Handler *hnd_add = NULL;
14static Ecore_Event_Handler *hnd_del = NULL;
15static Ecore_Event_Handler *hnd_data = NULL;
16static int clients = 0;
17static Ecore_Timer *quit_timer = NULL;
18
19static Eina_Bool
20_cb_quit_timer(void *data EINA_UNUSED)
21{
22 quit_timer = NULL;
23 quit();
24 return EINA_FALSE;
25}
26
27static void
28_broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size)
29{
30 Eina_List *clients = ecore_ipc_server_clients_get(svr);
31 Eina_List *l;
32 Ecore_Ipc_Client *cl;
33
34 EINA_LIST_FOREACH(clients, l, cl)
35 {
36 ecore_ipc_client_send(cl, major, minor, 0, 0, 0, data, size);
37 }
38}
39
40static char *
41_parse_str(void *data, int size)
42{
43 char *str = malloc(size + 1);
44 if (!str) return NULL;
45 memcpy(str, data, size);
46 str[size] = 0;
47 return str;
48}
49
50static Eina_List *
51_parse_strs(void *data, int size)
52{
53 Eina_List *list = NULL;
54 char *p, *p0 = NULL, *p1 = NULL, *e = (char *)data + size;
55
56 for (p = data; p < e; p++)
57 {
58 if (!p0)
59 {
60 if (*p)
61 {
62 p0 = p;
63 p1 = e;
64 }
65 }
66 if (!*p)
67 {
68 p1 = strdup(p0);
69 if (p1) list = eina_list_append(list, p1);
70 p0 = NULL;
71 }
72 }
73 if (p0)
74 {
75 p = malloc(p1 - p0 + 1);
76 if (p)
77 {
78 memcpy(p, p0, p1 - p0);
79 p[p1 - p0] = 0;
80 list = eina_list_append(list, p);
81 }
82 }
83 return list;
84}
85
86#define IPC_HEAD(_type) \
87 Ecore_Ipc_Event_Client_##_type *e = event; \
88 if (ecore_ipc_client_server_get(e->client) != ipc) \
89 return ECORE_CALLBACK_PASS_ON
90
91static Eina_Bool
92_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
93{
94 IPC_HEAD(Add);
95 if (quit_timer)
96 {
97 ecore_timer_del(quit_timer);
98 quit_timer = NULL;
99 }
100 clients++;
101 return ECORE_CALLBACK_DONE;
102}
103
104static Eina_Bool
105_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
106{
107 IPC_HEAD(Del);
108 clients--;
109 if (clients == 0)
110 {
111 if (quit_timer) ecore_timer_del(quit_timer);
112 quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL);
113 }
114 return ECORE_CALLBACK_DONE;
115}
116
117static Eina_Bool
118_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
119{
120 Eina_List *strs;
121 char *s;
122 IPC_HEAD(Data);
123 if (e->major == 1) // register lang
124 { // input: str -> lang
125 if ((s = _parse_str(e->data, e->size)))
126 {
127 setenv("LANG", s, 1);
128 free(s);
129 }
130 // return if desktop cache exists (bool as minor)
131 ecore_ipc_client_send(e->client, 1 /* register reply */,
132 cache_desktop_exists(), 0, 0, 0, NULL, 0);
133 }
134 else if (e->major == 2) // add desktop dirs
135 { // input: array of str -> dirs
136 strs = _parse_strs(e->data, e->size);
137 EINA_LIST_FREE(strs, s)
138 {
139 cache_desktop_dir_add(s);
140 free(s);
141 }
142 }
143 else if (e->major == 3) // build desktop cache
144 { // input: str -> lang
145 if ((s = _parse_str(e->data, e->size)))
146 {
147 setenv("LANG", s, 1);
148 free(s);
149 }
150 cache_desktop_update();
151 }
152 else if (e->major == 4) // add icon dirs
153 { // input: array of str -> dirs
154 strs = _parse_strs(e->data, e->size);
155 EINA_LIST_FREE(strs, s)
156 {
157 cache_icon_dir_add(s);
158 free(s);
159 }
160 }
161 else if (e->major == 5) // add icon exts
162 { // input: array of str -> exts
163 strs = _parse_strs(e->data, e->size);
164 EINA_LIST_FREE(strs, s)
165 {
166 cache_icon_ext_add(s);
167 free(s);
168 }
169 }
170 return ECORE_CALLBACK_DONE;
171}
172
173///////////////////////////////////////////////////////////////////////////
174
175void
176send_signal_icon_cache_update(Eina_Bool update)
177{
178 _broadcast(ipc, 2 /* icon cache update */, update, NULL, 0);
179}
180
181void
182send_signal_desktop_cache_update(Eina_Bool update)
183{
184 _broadcast(ipc, 3 /* desktop cache update */, update, NULL, 0);
185}
186
187Eina_Bool
188ipc_init(void)
189{
190 if (init > 0) return EINA_TRUE;
191 if (!ecore_ipc_init()) return EINA_FALSE;
192 ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL);
193 if (!ipc)
194 {
195 ecore_ipc_shutdown();
196 return EINA_FALSE;
197 }
198 quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL);
199 hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
200 _cb_client_add, NULL);
201 hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
202 _cb_client_del, NULL);
203 hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
204 _cb_client_data, NULL);
205 init++;
206 return EINA_TRUE;
207}
208
209Eina_Bool
210ipc_shutdown(void)
211{
212 if (init <= 0) return EINA_TRUE;
213 init--;
214 if (init > 0) return EINA_TRUE;
215 ecore_ipc_server_del(ipc);
216 ecore_event_handler_del(hnd_add);
217 ecore_event_handler_del(hnd_del);
218 ecore_event_handler_del(hnd_data);
219 ipc = NULL;
220 hnd_add = NULL;
221 hnd_del = NULL;
222 hnd_data = NULL;
223 ecore_ipc_shutdown();
224 return EINA_TRUE;
225}
226
diff --git a/src/bin/efreet/efreetd_dbus.h b/src/bin/efreet/efreetd_ipc.h
index 9e9fd70700..288f311add 100644
--- a/src/bin/efreet/efreetd_dbus.h
+++ b/src/bin/efreet/efreetd_ipc.h
@@ -1,10 +1,10 @@
1#ifndef __EFREETD_DBUS_H 1#ifndef __EFREETD_IPC_H
2#define __EFREETD_DBUS_H 2#define __EFREETD_IPC_H
3 3
4void send_signal_icon_cache_update(Eina_Bool update); 4void send_signal_icon_cache_update(Eina_Bool update);
5void send_signal_desktop_cache_update(Eina_Bool update); 5void send_signal_desktop_cache_update(Eina_Bool update);
6 6
7Eina_Bool dbus_init(void); 7Eina_Bool ipc_init(void);
8Eina_Bool dbus_shutdown(void); 8Eina_Bool ipc_shutdown(void);
9 9
10#endif 10#endif