ecore_wl2_display: Fix waiting for window server is ready 67/308167/1 accepted/tizen/unified/20240320.110708 accepted/tizen/unified/20240320.151920 accepted/tizen/unified/x/20240326.073632
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 19 Mar 2024 03:00:11 +0000 (12:00 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 19 Mar 2024 03:03:39 +0000 (12:03 +0900)
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 <h.jhun@samsung.com>
src/lib/ecore_wl2/ecore_wl2_display.c

index c0e2a0e..9e67513 100644 (file)
@@ -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);