summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2019-02-13 14:58:10 +0000
committerDerek Foreman <derek.foreman.samsung@gmail.com>2019-02-13 10:33:41 -0600
commit87cf5188b466d3fa1e8c8ff7ad6d5039b28e298a (patch)
tree5b3ba89f7da4808c07f287141229f204728dbc4e
parent66ce295fc9d09a0ba1454d25ca7b4e32a51c9553 (diff)
ecore_wl2: Make our wayland socket handling thread safe
By using the prepare read code properly we can do wayland dispatch of multiple queues in multiple threads. I'm not advocating we ever do so, but if a library (perhaps a gl implementation) wants to dispatch its own queue, and that happens in a separate thread from our event loop, we probably don't want the world to explode. Reviewed-by: Chris Michael <cp.michael@samsung.com> Differential Revision: https://phab.enlightenment.org/D7915
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_display.c73
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_private.h1
2 files changed, 34 insertions, 40 deletions
diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c
index a3af818ca4..8699dfaace 100644
--- a/src/lib/ecore_wl2/ecore_wl2_display.c
+++ b/src/lib/ecore_wl2/ecore_wl2_display.c
@@ -10,7 +10,6 @@
10static Eina_Hash *_server_displays = NULL; 10static Eina_Hash *_server_displays = NULL;
11static Eina_Hash *_client_displays = NULL; 11static Eina_Hash *_client_displays = NULL;
12 12
13static Eina_Bool _cb_connect_idle(void *data);
14static Eina_Bool _cb_connect_data(void *data, Ecore_Fd_Handler *hdl); 13static Eina_Bool _cb_connect_data(void *data, Ecore_Fd_Handler *hdl);
15static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync); 14static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync);
16 15
@@ -475,8 +474,6 @@ _recovery_timer_add(Ecore_Wl2_Display *ewd)
475 Ecore_Wl2_Window *window; 474 Ecore_Wl2_Window *window;
476 475
477 eina_hash_free_buckets(ewd->globals); 476 eina_hash_free_buckets(ewd->globals);
478 ecore_idle_enterer_del(ewd->idle_enterer);
479 ewd->idle_enterer = NULL;
480 477
481 ecore_main_fd_handler_del(ewd->fd_hdl); 478 ecore_main_fd_handler_del(ewd->fd_hdl);
482 ewd->fd_hdl = NULL; 479 ewd->fd_hdl = NULL;
@@ -528,6 +525,30 @@ _begin_recovery_maybe(Ecore_Wl2_Display *ewd, int code)
528 } 525 }
529} 526}
530 527
528static void
529_cb_connect_pre(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
530{
531 Ecore_Wl2_Display *ewd = data;
532 int ret = 0, code;
533
534 while ((wl_display_prepare_read(ewd->wl.display) != 0) && (ret >= 0))
535 ret = wl_display_dispatch_pending(ewd->wl.display);
536
537 if (ret < 0) goto err;
538
539 ret = wl_display_get_error(ewd->wl.display);
540 if (ret < 0) goto err;
541
542 return;
543
544err:
545 code = errno;
546 if ((ret < 0) && (code != EAGAIN))
547 {
548 _begin_recovery_maybe(ewd, code);
549 }
550}
551
531static Eina_Bool 552static Eina_Bool
532_cb_connect_data(void *data, Ecore_Fd_Handler *hdl) 553_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
533{ 554{
@@ -536,17 +557,20 @@ _cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
536 557
537 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ)) 558 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
538 { 559 {
539 ret = wl_display_dispatch(ewd->wl.display); 560 ret = wl_display_read_events(ewd->wl.display);
540 code = errno; 561 code = errno;
541 if ((ret < 0) && (code != EAGAIN)) goto err; 562 if ((ret < 0) && (code != EAGAIN)) goto err;
542 } 563 }
564 else
565 wl_display_cancel_read(ewd->wl.display);
543 566
567 wl_display_dispatch_pending(ewd->wl.display);
544 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE)) 568 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
545 { 569 {
546 ret = wl_display_flush(ewd->wl.display); 570 ret = wl_display_flush(ewd->wl.display);
547 code = errno; 571 code = errno;
548 if (ret >= 0) 572 if (ret >= 0)
549 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ); 573 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ | ECORE_FD_ALWAYS);
550 574
551 if ((ret < 0) && (code != EAGAIN)) goto err; 575 if ((ret < 0) && (code != EAGAIN)) goto err;
552 } 576 }
@@ -572,34 +596,6 @@ _cb_globals_hash_del(void *data)
572 free(global); 596 free(global);
573} 597}
574 598
575static Eina_Bool
576_cb_connect_idle(void *data)
577{
578 Ecore_Wl2_Display *ewd = data;
579 int ret = 0, code;
580
581 ret = wl_display_get_error(ewd->wl.display);
582 code = errno;
583 if (ret < 0) goto err;
584
585 ret = wl_display_dispatch_pending(ewd->wl.display);
586 code = errno;
587 if (ret < 0) goto err;
588
589 return ECORE_CALLBACK_RENEW;
590
591err:
592 if ((ret < 0) && (code != EAGAIN))
593 {
594 ewd->idle_enterer = NULL;
595 _begin_recovery_maybe(ewd, code);
596
597 return ECORE_CALLBACK_CANCEL;
598 }
599
600 return ECORE_CALLBACK_RENEW;
601}
602
603static Ecore_Wl2_Global * 599static Ecore_Wl2_Global *
604_ecore_wl2_global_find(Ecore_Wl2_Display *ewd, const char *interface) 600_ecore_wl2_global_find(Ecore_Wl2_Display *ewd, const char *interface)
605{ 601{
@@ -742,10 +738,11 @@ _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync)
742 738
743 ewd->fd_hdl = 739 ewd->fd_hdl =
744 ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display), 740 ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
745 ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR, 741 ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR | ECORE_FD_ALWAYS,
746 _cb_connect_data, ewd, NULL, NULL); 742 _cb_connect_data, ewd, NULL, ewd);
747 743
748 ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd); 744 ecore_main_fd_handler_prepare_callback_set
745 (ewd->fd_hdl, _cb_connect_pre, ewd);
749 746
750 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_CONNECT); 747 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_CONNECT);
751 return EINA_TRUE; 748 return EINA_TRUE;
@@ -768,8 +765,6 @@ _ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
768 EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output) 765 EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
769 _ecore_wl2_output_del(output); 766 _ecore_wl2_output_del(output);
770 767
771 if (ewd->idle_enterer) ecore_idle_enterer_del(ewd->idle_enterer);
772
773 if (ewd->fd_hdl) ecore_main_fd_handler_del(ewd->fd_hdl); 768 if (ewd->fd_hdl) ecore_main_fd_handler_del(ewd->fd_hdl);
774 769
775 eina_hash_free(ewd->globals); 770 eina_hash_free(ewd->globals);
@@ -1160,7 +1155,7 @@ ecore_wl2_display_flush(Ecore_Wl2_Display *display)
1160 if (code == EAGAIN) 1155 if (code == EAGAIN)
1161 { 1156 {
1162 ecore_main_fd_handler_active_set(display->fd_hdl, 1157 ecore_main_fd_handler_active_set(display->fd_hdl,
1163 (ECORE_FD_READ | ECORE_FD_WRITE)); 1158 (ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ALWAYS));
1164 return; 1159 return;
1165 } 1160 }
1166 1161
diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h
index e62ea5f8ea..9b6d4f7e49 100644
--- a/src/lib/ecore_wl2/ecore_wl2_private.h
+++ b/src/lib/ecore_wl2/ecore_wl2_private.h
@@ -102,7 +102,6 @@ struct _Ecore_Wl2_Display
102 102
103 struct xkb_context *xkb_context; 103 struct xkb_context *xkb_context;
104 104
105 Ecore_Idle_Enterer *idle_enterer;
106 Ecore_Fd_Handler *fd_hdl; 105 Ecore_Fd_Handler *fd_hdl;
107 106
108 Eina_Hash *globals; 107 Eina_Hash *globals;