From 63dd89e8f9cae172b7acba1503adbd7d1d7970d0 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 19 Mar 2024 12:00:11 +0900 Subject: [PATCH] ecore_wl2_display: Fix waiting for window server is ready To prevent a race condition, the ecore-wl2 checks whether the file exists or not using access() after calling inotify_add_watch(). The implementation related to inotify event is moved to the _ecore_wl2_display_wait() function. Change-Id: Ie51e6af644d01b962878df1e5d1d35f9539c16a3 Signed-off-by: Hwankyu Jhun --- src/lib/ecore_wl2/ecore_wl2_display.c | 71 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index c0e2a0e..9e67513 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -1670,37 +1670,58 @@ _ecore_wl2_display_sync_add(Ecore_Wl2_Display *ewd) #define RUN_WM_READY_FILE "/run/.wm_ready" static Eina_Bool +_ecore_wl2_display_wait(Ecore_Wl2_Display *ewd) +{ + int fd; + int wd; + int i = 0; + int event_size; + ssize_t size; + unsigned char buf[128]; + struct inotify_event *event; + + fd = inotify_init(); + if (fd == -1) return EINA_FALSE; + + wd = inotify_add_watch(fd, RUN_WM_READY_FILE, IN_MODIFY | IN_CREATE); + if (wd == -1) + { + close(fd); + return EINA_FALSE; + } + + if (access(RUN_WM_READY_FILE, F_OK) == 0) + { + ERR("The server is ready"); + inotify_rm_watch(fd, wd); + close(fd); + return EINA_TRUE; + } + + ERR("Wait for the server to be ready.[fd: %d, wd: %d", fd, wd); + size = read(fd, buf, sizeof(buf)); + while ((i + (int)sizeof(struct inotify_event)) <= (int)size) + { + event = (struct inotify_event *)&buf[i]; + event_size = sizeof(struct inotify_event) + event->len; + if ((event_size + i) > size) break; + i += event_size; + if (event->mask & IN_CREATE | event->mask & IN_MODIFY) break; + } + + inotify_rm_watch(fd, wd); + close(fd); + return EINA_TRUE; +} + +static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync) { /* try to connect to wayland display with this name */ ewd->wl.display = wl_display_connect(ewd->name); if (!ewd->wl.display) { #ifdef HAVE_SYS_INOTIFY_H - int fd = 0, wd = 0; - int i = 0; - int event_size = 0; - unsigned char buf[128]; - struct inotify_event *event; - - fd = inotify_init(); - if (fd == -1) return EINA_FALSE; - - wd = inotify_add_watch(fd, RUN_WM_READY_FILE, IN_MODIFY | IN_CREATE); - if (wd == -1) return EINA_FALSE; - - ERR("Wait for the server to be ready.[fd: %d, wd: %d",fd,wd); - ssize_t size = read(fd, buf, sizeof(buf)); - while ((i + (int) sizeof(struct inotify_event)) <= (int) size) - { - event = (struct inotify_event *) &buf[i]; - event_size = sizeof(struct inotify_event) + event->len; - if ((event_size + i) > size) break; - i += event_size; - if (event->mask & IN_CREATE | event->mask & IN_MODIFY) break; - } - - inotify_rm_watch(fd, wd); - close(fd); + if (!_ecore_wl2_display_wait(ewd)) return EINA_FALSE; ewd->wl.display = wl_display_connect(ewd->name); ERR("Server is ready, wl.display is created %p", ewd->wl.display); -- 2.7.4