forked from enlightenment/efl
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. @fixdevs/avilog/adding_eolian_info
parent
c6011926ba
commit
5abfefe99e
11 changed files with 461 additions and 490 deletions
@ -1,4 +0,0 @@ |
||||
[D-BUS Service] |
||||
Name=org.enlightenment.Efreet |
||||
Exec=@prefix@/bin/efreetd |
||||
@systemd_dbus_prefix@SystemdService=efreet.service |
@ -1,262 +0,0 @@ |
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include <Ecore.h> |
||||
#include <Eldbus.h> |
||||
|
||||
#include "efreetd.h" |
||||
#include "efreetd_cache.h" |
||||
|
||||
#define BUS "org.enlightenment.Efreet" |
||||
#define PATH "/org/enlightenment/Efreet" |
||||
#define INTERFACE "org.enlightenment.Efreet" |
||||
|
||||
/* internal */ |
||||
enum |
||||
{ |
||||
EFREET_SIGNAL_ICON_CACHE_UPDATE = 0, |
||||
EFREET_SIGNAL_DESKTOP_CACHE_UPDATE |
||||
}; |
||||
|
||||
static Eldbus_Connection *conn; |
||||
static Eldbus_Service_Interface *iface; |
||||
|
||||
static Ecore_Timer *_shutdown = NULL; |
||||
static int clients = 0; |
||||
|
||||
static Eina_Bool |
||||
do_shutdown(void *data EINA_UNUSED) |
||||
{ |
||||
quit(); |
||||
return ECORE_CALLBACK_CANCEL; |
||||
} |
||||
|
||||
static void |
||||
disconnected(void *context EINA_UNUSED, Eldbus_Connection *connection EINA_UNUSED, void *event_info EINA_UNUSED) |
||||
{ |
||||
INF("disconnected"); |
||||
quit(); |
||||
} |
||||
|
||||
static void |
||||
client_name_owner_changed_cb(void *data EINA_UNUSED, const char *bus, const char *old_id EINA_UNUSED, const char *new_id) |
||||
{ |
||||
if (new_id[0]) |
||||
return; |
||||
eldbus_name_owner_changed_callback_del(conn, bus, |
||||
client_name_owner_changed_cb, NULL); |
||||
clients--; |
||||
if (clients <= 0) |
||||
{ |
||||
clients = 0; |
||||
if (_shutdown) ecore_timer_del(_shutdown); |
||||
_shutdown = ecore_timer_add(10.0, do_shutdown, NULL); |
||||
} |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
do_register(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message) |
||||
{ |
||||
Eldbus_Message *reply; |
||||
const char *lang; |
||||
|
||||
if (!eldbus_message_arguments_get(message, "s", &lang)) |
||||
{ |
||||
ERR("Error getting arguments."); |
||||
return NULL; |
||||
} |
||||
setenv("LANG", lang, 1); |
||||
|
||||
clients++; |
||||
if (_shutdown) ecore_timer_del(_shutdown); |
||||
_shutdown = NULL; |
||||
|
||||
eldbus_name_owner_changed_callback_add(conn, |
||||
eldbus_message_sender_get(message), |
||||
client_name_owner_changed_cb, NULL, |
||||
EINA_FALSE); |
||||
reply = eldbus_message_method_return_new(message); |
||||
eldbus_message_arguments_append(reply, "b", cache_desktop_exists()); |
||||
return reply; |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
add_desktop_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message) |
||||
{ |
||||
Eldbus_Message_Iter *array = NULL; |
||||
const char *dir; |
||||
|
||||
if (!eldbus_message_arguments_get(message, "as", &array)) |
||||
{ |
||||
ERR("Error getting arguments."); |
||||
return NULL; |
||||
} |
||||
|
||||
while (eldbus_message_iter_get_and_next(array, 's', &dir)) |
||||
{ |
||||
cache_desktop_dir_add(dir); |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
add_icon_dirs(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message) |
||||
{ |
||||
Eldbus_Message_Iter *array = NULL; |
||||
const char *dir; |
||||
|
||||
if (!eldbus_message_arguments_get(message, "as", &array)) |
||||
{ |
||||
ERR("Error getting arguments."); |
||||
return NULL; |
||||
} |
||||
|
||||
while (eldbus_message_iter_get_and_next(array, 's', &dir)) |
||||
{ |
||||
cache_icon_dir_add(dir); |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
build_desktop_cache(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message EINA_UNUSED) |
||||
{ |
||||
const char *lang; |
||||
|
||||
if (!eldbus_message_arguments_get(message, "s", &lang)) |
||||
{ |
||||
ERR("Error getting arguments."); |
||||
return NULL; |
||||
} |
||||
setenv("LANG", lang, 1); |
||||
|
||||
cache_desktop_update(); |
||||
return NULL; |
||||
} |
||||
|
||||
static Eldbus_Message * |
||||
add_icon_exts(const Eldbus_Service_Interface *ifc EINA_UNUSED, const Eldbus_Message *message) |
||||
{ |
||||
Eldbus_Message_Iter *array = NULL; |
||||
const char *ext; |
||||
|
||||
if (!eldbus_message_arguments_get(message, "as", &array)) |
||||
{ |
||||
ERR("Error getting arguments."); |
||||
return NULL; |
||||
} |
||||
|
||||
while (eldbus_message_iter_get_and_next(array, 's', &ext)) |
||||
{ |
||||
cache_icon_ext_add(ext); |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static const Eldbus_Signal signals[] = { |
||||
[EFREET_SIGNAL_ICON_CACHE_UPDATE] = {"IconCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0}, |
||||
[EFREET_SIGNAL_DESKTOP_CACHE_UPDATE] = {"DesktopCacheUpdate", ELDBUS_ARGS({ "b", "update" }), 0}, |
||||
{ NULL, NULL, 0 } |
||||
}; |
||||
|
||||
static const Eldbus_Method methods[] = { |
||||
{ |
||||
"Register", ELDBUS_ARGS({"s", "lang info"}), ELDBUS_ARGS({"b", "cache exists"}), |
||||
do_register, 0 |
||||
}, |
||||
{ |
||||
"AddDesktopDirs", ELDBUS_ARGS({"as", "dirs"}), NULL, |
||||
add_desktop_dirs, ELDBUS_METHOD_FLAG_NOREPLY |
||||
}, |
||||
{ |
||||
"BuildDesktopCache", ELDBUS_ARGS({"s", "lang info"}), NULL, |
||||
build_desktop_cache, ELDBUS_METHOD_FLAG_NOREPLY |
||||
}, |
||||
{ |
||||
"AddIconDirs", ELDBUS_ARGS({"as", "dirs"}), NULL, |
||||
add_icon_dirs, ELDBUS_METHOD_FLAG_NOREPLY |
||||
}, |
||||
{ |
||||
"AddIconExts", ELDBUS_ARGS({"as", "exts"}), NULL, |
||||
add_icon_exts, ELDBUS_METHOD_FLAG_NOREPLY |
||||
}, |
||||
{ NULL, NULL, NULL, NULL, 0 } |
||||
}; |
||||
|
||||
static const Eldbus_Service_Interface_Desc desc = { |
||||
INTERFACE, methods, signals, NULL, NULL, NULL |
||||
}; |
||||
|
||||
static void |
||||
on_name_request(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) |
||||
{ |
||||
unsigned int reply; |
||||
|
||||
if (eldbus_message_error_get(msg, NULL, NULL)) |
||||
{ |
||||
ERR("error on on_name_request"); |
||||
quit(); |
||||
return; |
||||
} |
||||
|
||||
if (!eldbus_message_arguments_get(msg, "u", &reply)) |
||||
{ |
||||
ERR("error getting arguments on on_name_request"); |
||||
quit(); |
||||
return; |
||||
} |
||||
|
||||
if (reply != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER) |
||||
{ |
||||
ERR("error name already in use"); |
||||
quit(); |
||||
return; |
||||
} |
||||
INF("name requested"); |
||||
} |
||||
|
||||
/* external */ |
||||
void |
||||
send_signal_icon_cache_update(Eina_Bool update) |
||||
{ |
||||
eldbus_service_signal_emit(iface, EFREET_SIGNAL_ICON_CACHE_UPDATE, update); |
||||
} |
||||
|
||||
void |
||||
send_signal_desktop_cache_update(Eina_Bool update) |
||||
{ |
||||
eldbus_service_signal_emit(iface, EFREET_SIGNAL_DESKTOP_CACHE_UPDATE, update); |
||||
} |
||||
|
||||
Eina_Bool |
||||
dbus_init(void) |
||||
{ |
||||
if (!eldbus_init()) return EINA_FALSE; |
||||
|
||||
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION); |
||||
if (!conn) goto conn_error; |
||||
|
||||
eldbus_connection_event_callback_add(conn, |
||||
ELDBUS_CONNECTION_EVENT_DISCONNECTED, disconnected, NULL); |
||||
iface = eldbus_service_interface_register(conn, PATH, &desc); |
||||
eldbus_name_request(conn, BUS, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, |
||||
on_name_request, NULL); |
||||
|
||||
return EINA_TRUE; |
||||
conn_error: |
||||
eldbus_shutdown(); |
||||
return EINA_FALSE; |
||||
} |
||||
|
||||
Eina_Bool |
||||
dbus_shutdown(void) |
||||
{ |
||||
eldbus_connection_unref(conn); |
||||
eldbus_shutdown(); |
||||
return EINA_TRUE; |
||||
|
||||
} |
@ -0,0 +1,226 @@ |
||||
#ifdef HAVE_CONFIG_H |
||||
# include <config.h> |
||||
#endif |
||||
|
||||
#include <Ecore.h> |
||||
#include <Ecore_Ipc.h> |
||||
|
||||
#include "efreetd.h" |
||||
#include "efreetd_cache.h" |
||||
|
||||
static int init = 0; |
||||
static Ecore_Ipc_Server *ipc = NULL; |
||||
static Ecore_Event_Handler *hnd_add = NULL; |
||||
static Ecore_Event_Handler *hnd_del = NULL; |
||||
static Ecore_Event_Handler *hnd_data = NULL; |
||||
static int clients = 0; |
||||
static Ecore_Timer *quit_timer = NULL; |
||||
|
||||
static Eina_Bool |
||||
_cb_quit_timer(void *data EINA_UNUSED) |
||||
{ |
||||
quit_timer = NULL; |
||||
quit(); |
||||
return EINA_FALSE; |
||||
} |
||||
|
||||
static void |
||||
_broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size) |
||||
{ |
||||
Eina_List *clients = ecore_ipc_server_clients_get(svr); |
||||
Eina_List *l; |
||||
Ecore_Ipc_Client *cl; |
||||
|
||||
EINA_LIST_FOREACH(clients, l, cl) |
||||
{ |
||||
ecore_ipc_client_send(cl, major, minor, 0, 0, 0, data, size); |
||||
} |
||||
} |
||||
|
||||
static char * |
||||
_parse_str(void *data, int size) |
||||
{ |
||||
char *str = malloc(size + 1); |
||||
if (!str) return NULL; |
||||
memcpy(str, data, size); |
||||
str[size] = 0; |
||||
return str; |
||||
} |
||||
|
||||
static Eina_List * |
||||
_parse_strs(void *data, int size) |
||||
{ |
||||
Eina_List *list = NULL; |
||||
char *p, *p0 = NULL, *p1 = NULL, *e = (char *)data + size; |
||||
|
||||
for (p = data; p < e; p++) |
||||
{ |
||||
if (!p0) |
||||
{ |
||||
if (*p) |
||||
{ |
||||
p0 = p; |
||||
p1 = e; |
||||
} |
||||
} |
||||
if (!*p) |
||||
{ |
||||
p1 = strdup(p0); |
||||
if (p1) list = eina_list_append(list, p1); |
||||
p0 = NULL; |
||||
} |
||||
} |
||||
if (p0) |
||||
{ |
||||
p = malloc(p1 - p0 + 1); |
||||
if (p) |
||||
{ |
||||
memcpy(p, p0, p1 - p0); |
||||
p[p1 - p0] = 0; |
||||
list = eina_list_append(list, p); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
#define IPC_HEAD(_type) \ |
||||
Ecore_Ipc_Event_Client_##_type *e = event; \
|
||||
if (ecore_ipc_client_server_get(e->client) != ipc) \
|
||||
return ECORE_CALLBACK_PASS_ON |
||||
|
||||
static Eina_Bool |
||||
_cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) |
||||
{ |
||||
IPC_HEAD(Add); |
||||
if (quit_timer) |
||||
{ |
||||
ecore_timer_del(quit_timer); |
||||
quit_timer = NULL; |
||||
} |
||||
clients++; |
||||
return ECORE_CALLBACK_DONE; |
||||
} |
||||
|
||||
static Eina_Bool |
||||
_cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) |
||||
{ |
||||
IPC_HEAD(Del); |
||||
clients--; |
||||
if (clients == 0) |
||||
{ |
||||
if (quit_timer) ecore_timer_del(quit_timer); |
||||
quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL); |
||||
} |
||||
return ECORE_CALLBACK_DONE; |
||||
} |
||||
|
||||
static Eina_Bool |
||||
_cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) |
||||
{ |
||||
Eina_List *strs; |
||||
char *s; |
||||
IPC_HEAD(Data); |
||||
if (e->major == 1) // register lang
|
||||
{ // input: str -> lang
|
||||
if ((s = _parse_str(e->data, e->size))) |
||||
{ |
||||
setenv("LANG", s, 1); |
||||
free(s); |
||||
} |
||||
// return if desktop cache exists (bool as minor)
|
||||
ecore_ipc_client_send(e->client, 1 /* register reply */, |
||||
cache_desktop_exists(), 0, 0, 0, NULL, 0); |
||||
} |
||||
else if (e->major == 2) // add desktop dirs
|
||||
{ // input: array of str -> dirs
|
||||
strs = _parse_strs(e->data, e->size); |
||||
EINA_LIST_FREE(strs, s) |
||||
{ |
||||
cache_desktop_dir_add(s); |
||||
free(s); |
||||
} |
||||
} |
||||
else if (e->major == 3) // build desktop cache
|
||||
{ // input: str -> lang
|
||||
if ((s = _parse_str(e->data, e->size))) |
||||
{ |
||||
setenv("LANG", s, 1); |
||||
free(s); |
||||
} |
||||
cache_desktop_update(); |
||||
} |
||||
else if (e->major == 4) // add icon dirs
|
||||
{ // input: array of str -> dirs
|
||||
strs = _parse_strs(e->data, e->size); |
||||
EINA_LIST_FREE(strs, s) |
||||
{ |
||||
cache_icon_dir_add(s); |
||||
free(s); |
||||
} |
||||
} |
||||
else if (e->major == 5) // add icon exts
|
||||
{ // input: array of str -> exts
|
||||
strs = _parse_strs(e->data, e->size); |
||||
EINA_LIST_FREE(strs, s) |
||||
{ |
||||
cache_icon_ext_add(s); |
||||
free(s); |
||||
} |
||||
} |
||||
return ECORE_CALLBACK_DONE; |
||||
} |
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void |
||||
send_signal_icon_cache_update(Eina_Bool update) |
||||
{ |
||||
_broadcast(ipc, 2 /* icon cache update */, update, NULL, 0); |
||||
} |
||||
|
||||
void |
||||
send_signal_desktop_cache_update(Eina_Bool update) |
||||
{ |
||||
_broadcast(ipc, 3 /* desktop cache update */, update, NULL, 0); |
||||
} |
||||
|
||||
Eina_Bool |
||||
ipc_init(void) |
||||
{ |
||||
if (init > 0) return EINA_TRUE; |
||||
if (!ecore_ipc_init()) return EINA_FALSE; |
||||
ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, "efreetd", 0, NULL); |
||||
if (!ipc) |
||||
{ |
||||
ecore_ipc_shutdown(); |
||||
return EINA_FALSE; |
||||
} |
||||
quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL); |
||||
hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, |
||||
_cb_client_add, NULL); |
||||
hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, |
||||
_cb_client_del, NULL); |
||||
hnd_data = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, |
||||
_cb_client_data, NULL); |
||||
init++; |
||||
return EINA_TRUE; |
||||
} |
||||
|
||||
Eina_Bool |
||||
ipc_shutdown(void) |
||||
{ |
||||
if (init <= 0) return EINA_TRUE; |
||||
init--; |
||||
if (init > 0) return EINA_TRUE; |
||||
ecore_ipc_server_del(ipc); |
||||
ecore_event_handler_del(hnd_add); |
||||
ecore_event_handler_del(hnd_del); |
||||
ecore_event_handler_del(hnd_data); |
||||
ipc = NULL; |
||||
hnd_add = NULL; |
||||
hnd_del = NULL; |
||||
hnd_data = NULL; |
||||
ecore_ipc_shutdown(); |
||||
return EINA_TRUE; |
||||
} |
||||
|
@ -1,10 +1,10 @@ |
||||
#ifndef __EFREETD_DBUS_H |
||||
#define __EFREETD_DBUS_H |
||||
#ifndef __EFREETD_IPC_H |
||||
#define __EFREETD_IPC_H |
||||
|
||||
void send_signal_icon_cache_update(Eina_Bool update); |
||||
void send_signal_desktop_cache_update(Eina_Bool update); |
||||
|
||||
Eina_Bool dbus_init(void); |
||||
Eina_Bool dbus_shutdown(void); |
||||
Eina_Bool ipc_init(void); |
||||
Eina_Bool ipc_shutdown(void); |
||||
|
||||
#endif |
@ -1,7 +0,0 @@ |
||||
[Unit] |
||||
Description=Efreet Enlightenment FreeDesktop.Org Daemon |
||||
|
||||
[Service] |
||||
Type=dbus |
||||
BusName=org.enlightenment.Efreet |
||||
ExecStart=@prefix@/bin/efreetd |
Loading…
Reference in new issue