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
commit5760b3f335d842767139d07fe08b4157382e1ad3 (patch)
tree466fafdf14cef821b1d686c2b823c9a79e458254
parent7927cfefe3a4c45b6b86ed36bb284d009e154f19 (diff)
eeze: simplify watch code and make it fork-safe
avoid reads from parent process's udev fds
-rw-r--r--src/lib/eeze/eeze_udev_watch.c139
1 files changed, 73 insertions, 66 deletions
diff --git a/src/lib/eeze/eeze_udev_watch.c b/src/lib/eeze/eeze_udev_watch.c
index eccd61c3d1..7245f9d0a6 100644
--- a/src/lib/eeze/eeze_udev_watch.c
+++ b/src/lib/eeze/eeze_udev_watch.c
@@ -11,22 +11,14 @@
11#include <Eeze.h> 11#include <Eeze.h>
12#include "eeze_udev_private.h" 12#include "eeze_udev_private.h"
13 13
14static Eina_Inlist *watches;
15
14/* opaque */ 16/* opaque */
15struct Eeze_Udev_Watch 17struct Eeze_Udev_Watch
16{ 18{
17 _udev_monitor *mon; 19 EINA_INLIST;
18 Ecore_Fd_Handler *handler; 20 Ecore_Fd_Handler *handler;
19 Eeze_Udev_Type type; 21 Eeze_Udev_Watch_Cb func;
20 void *data;
21};
22
23/* private */
24struct _store_data
25{
26 void (*func)(const char *,
27 Eeze_Udev_Event,
28 void *,
29 Eeze_Udev_Watch *);
30 void *data; 22 void *data;
31 Eeze_Udev_Event event; 23 Eeze_Udev_Event event;
32 _udev_monitor *mon; 24 _udev_monitor *mon;
@@ -42,18 +34,17 @@ static Eina_Bool
42_get_syspath_from_watch(void *data, 34_get_syspath_from_watch(void *data,
43 Ecore_Fd_Handler *fd_handler) 35 Ecore_Fd_Handler *fd_handler)
44{ 36{
45 struct _store_data *store = data; 37 Eeze_Udev_Watch *watch = data;
46 _udev_device *device = NULL, *parent, *tmpdev; 38 _udev_device *device = NULL, *parent, *tmpdev;
47 const char *ret, *test; 39 const char *ret, *test;
48 Eeze_Udev_Watch_Cb func = store->func; 40 Eeze_Udev_Watch_Cb func = watch->func;
49 void *sdata = store->data; 41 void *sdata = watch->data;
50 Eeze_Udev_Watch *watch = store->watch;
51 int event = 0; 42 int event = 0;
52 43
53 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) 44 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
54 return EINA_TRUE; 45 return EINA_TRUE;
55 46
56 device = udev_monitor_receive_device(store->mon); 47 device = udev_monitor_receive_device(watch->mon);
57 48
58 if (!device) 49 if (!device)
59 return EINA_TRUE; 50 return EINA_TRUE;
@@ -62,44 +53,44 @@ _get_syspath_from_watch(void *data,
62 || (!(ret = udev_device_get_syspath(device)))) 53 || (!(ret = udev_device_get_syspath(device))))
63 goto error; 54 goto error;
64 55
65 if (store->event) 56 if (watch->event)
66 { 57 {
67 if (!strcmp(test, "add")) 58 if (!strcmp(test, "add"))
68 { 59 {
69 if ((store->event != EEZE_UDEV_EVENT_NONE) && 60 if ((watch->event != EEZE_UDEV_EVENT_NONE) &&
70 ((store->event & EEZE_UDEV_EVENT_ADD) != EEZE_UDEV_EVENT_ADD)) 61 ((watch->event & EEZE_UDEV_EVENT_ADD) != EEZE_UDEV_EVENT_ADD))
71 goto error; 62 goto error;
72 63
73 event |= EEZE_UDEV_EVENT_ADD; 64 event |= EEZE_UDEV_EVENT_ADD;
74 } 65 }
75 else if (!strcmp(test, "remove")) 66 else if (!strcmp(test, "remove"))
76 { 67 {
77 if ((store->event != EEZE_UDEV_EVENT_NONE) && 68 if ((watch->event != EEZE_UDEV_EVENT_NONE) &&
78 ((store->event & EEZE_UDEV_EVENT_REMOVE) != EEZE_UDEV_EVENT_REMOVE)) 69 ((watch->event & EEZE_UDEV_EVENT_REMOVE) != EEZE_UDEV_EVENT_REMOVE))
79 goto error; 70 goto error;
80 71
81 event |= EEZE_UDEV_EVENT_REMOVE; 72 event |= EEZE_UDEV_EVENT_REMOVE;
82 } 73 }
83 else if (!strcmp(test, "change")) 74 else if (!strcmp(test, "change"))
84 { 75 {
85 if ((store->event != EEZE_UDEV_EVENT_NONE) && 76 if ((watch->event != EEZE_UDEV_EVENT_NONE) &&
86 ((store->event & EEZE_UDEV_EVENT_CHANGE) != EEZE_UDEV_EVENT_CHANGE)) 77 ((watch->event & EEZE_UDEV_EVENT_CHANGE) != EEZE_UDEV_EVENT_CHANGE))
87 goto error; 78 goto error;
88 79
89 event |= EEZE_UDEV_EVENT_CHANGE; 80 event |= EEZE_UDEV_EVENT_CHANGE;
90 } 81 }
91 else if (!strcmp(test, "online")) 82 else if (!strcmp(test, "online"))
92 { 83 {
93 if ((store->event != EEZE_UDEV_EVENT_NONE) && 84 if ((watch->event != EEZE_UDEV_EVENT_NONE) &&
94 ((store->event & EEZE_UDEV_EVENT_ONLINE) != EEZE_UDEV_EVENT_ONLINE)) 85 ((watch->event & EEZE_UDEV_EVENT_ONLINE) != EEZE_UDEV_EVENT_ONLINE))
95 goto error; 86 goto error;
96 87
97 event |= EEZE_UDEV_EVENT_ONLINE; 88 event |= EEZE_UDEV_EVENT_ONLINE;
98 } 89 }
99 else 90 else
100 { 91 {
101 if ((store->event != EEZE_UDEV_EVENT_NONE) && 92 if ((watch->event != EEZE_UDEV_EVENT_NONE) &&
102 ((store->event & EEZE_UDEV_EVENT_OFFLINE) != EEZE_UDEV_EVENT_OFFLINE)) 93 ((watch->event & EEZE_UDEV_EVENT_OFFLINE) != EEZE_UDEV_EVENT_OFFLINE))
103 goto error; 94 goto error;
104 95
105 event |= EEZE_UDEV_EVENT_OFFLINE; 96 event |= EEZE_UDEV_EVENT_OFFLINE;
@@ -108,7 +99,7 @@ _get_syspath_from_watch(void *data,
108 99
109 if ((event & EEZE_UDEV_EVENT_OFFLINE) || (event & EEZE_UDEV_EVENT_REMOVE)) 100 if ((event & EEZE_UDEV_EVENT_OFFLINE) || (event & EEZE_UDEV_EVENT_REMOVE))
110 goto out; 101 goto out;
111 switch (store->type) 102 switch (watch->type)
112 { 103 {
113 case EEZE_UDEV_TYPE_KEYBOARD: 104 case EEZE_UDEV_TYPE_KEYBOARD:
114 if ((!udev_device_get_property_value(device, "ID_INPUT_KEYBOARD")) && 105 if ((!udev_device_get_property_value(device, "ID_INPUT_KEYBOARD")) &&
@@ -279,28 +270,16 @@ error:
279 return EINA_TRUE; 270 return EINA_TRUE;
280} 271}
281 272
282EAPI Eeze_Udev_Watch * 273static Eina_Bool
283eeze_udev_watch_add(Eeze_Udev_Type type, 274_watch_init(Eeze_Udev_Watch *watch)
284 int event,
285 Eeze_Udev_Watch_Cb cb,
286 void *user_data)
287{ 275{
288 _udev_monitor *mon = NULL; 276 _udev_monitor *mon = NULL;
289 int fd; 277 int fd;
290 Ecore_Fd_Handler *handler; 278 Ecore_Fd_Handler *handler;
291 Eeze_Udev_Watch *watch = NULL;
292 struct _store_data *store = NULL;
293
294 if (!(store = calloc(1, sizeof(struct _store_data))))
295 return NULL;
296
297 if (!(watch = malloc(sizeof(Eeze_Udev_Watch))))
298 goto error;
299
300 if (!(mon = udev_monitor_new_from_netlink(udev, "udev"))) 279 if (!(mon = udev_monitor_new_from_netlink(udev, "udev")))
301 goto error; 280 goto error;
302 281
303 switch (type) 282 switch (watch->type)
304 { 283 {
305 case EEZE_UDEV_TYPE_JOYSTICK: 284 case EEZE_UDEV_TYPE_JOYSTICK:
306 case EEZE_UDEV_TYPE_KEYBOARD: 285 case EEZE_UDEV_TYPE_KEYBOARD:
@@ -367,49 +346,77 @@ eeze_udev_watch_add(Eeze_Udev_Type type,
367 goto error; 346 goto error;
368 347
369 fd = udev_monitor_get_fd(mon); 348 fd = udev_monitor_get_fd(mon);
370 store->func = cb; 349 watch->mon = mon;
371 store->data = user_data;
372 store->mon = mon;
373 store->type = type;
374 store->watch = watch;
375 store->event = event;
376 350
377 if (!(handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, 351 if (!(handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
378 _get_syspath_from_watch, store, NULL, NULL))) 352 _get_syspath_from_watch, watch, NULL, NULL)))
379 goto error; 353 goto error;
380 354
381 watch->mon = mon;
382 watch->handler = handler; 355 watch->handler = handler;
383 return watch; 356 return EINA_TRUE;
384error: 357error:
385 if (store)
386 free(store);
387 if (watch)
388 free(watch);
389 if (mon) 358 if (mon)
390 udev_monitor_unref(mon); 359 udev_monitor_unref(mon);
391 ERR("Could not create watch!"); 360 ERR("Could not create watch!");
361 return EINA_FALSE;
362}
363
364static void
365_eeze_udev_watch_reset()
366{
367 Eeze_Udev_Watch *watch;
368
369 EINA_INLIST_FOREACH(watches, watch)
370 {
371 ecore_main_fd_handler_del(watch->handler);
372 udev_monitor_unref(watch->mon);
373 watch->handler = NULL;
374 watch->mon = NULL;
375 _watch_init(watch);
376 }
377}
378
379EAPI Eeze_Udev_Watch *
380eeze_udev_watch_add(Eeze_Udev_Type type,
381 int event,
382 Eeze_Udev_Watch_Cb cb,
383 void *user_data)
384{
385 Eeze_Udev_Watch *watch = NULL;
386
387 watch = calloc(1, sizeof(Eeze_Udev_Watch));
388 EINA_SAFETY_ON_NULL_RETURN_VAL(watch, NULL);
389
390 watch->func = cb;
391 watch->data = user_data;
392 watch->type = type;
393 watch->watch = watch;
394 watch->event = event;
395 if (!_watch_init(watch)) goto error;
396 if (!watches)
397 ecore_fork_reset_callback_add(_eeze_udev_watch_reset, NULL);
398 watches = eina_inlist_append(watches, EINA_INLIST_GET(watch));
399 return watch;
400error:
401 free(watch);
392 return NULL; 402 return NULL;
393} 403}
394 404
395EAPI void * 405EAPI void *
396eeze_udev_watch_del(Eeze_Udev_Watch *watch) 406eeze_udev_watch_del(Eeze_Udev_Watch *watch)
397{ 407{
398 struct _store_data *sdata;
399 void *ret = NULL; 408 void *ret = NULL;
400 409
401 if ((!watch) || (!watch->mon) || (!watch->handler)) 410 if (!watch)
402 return NULL; 411 return NULL;
403 412
404 sdata = ecore_main_fd_handler_del(watch->handler); 413 ecore_main_fd_handler_del(watch->handler);
405 udev_monitor_unref(watch->mon); 414 udev_monitor_unref(watch->mon);
406 415
407 if (sdata) 416 ret = watch->data;
408 { 417 watches = eina_inlist_remove(watches, EINA_INLIST_GET(watch));
409 ret = sdata->data; 418 if (!watches)
410 free(sdata); 419 ecore_fork_reset_callback_del(_eeze_udev_watch_reset, NULL);
411 }
412
413 free(watch); 420 free(watch);
414 return ret; 421 return ret;
415} 422}