ecore-file: use hash list for inotify monitor tracking
authorMike Blumenkrantz <zmike@osg.samsung.com>
Thu, 23 Apr 2015 12:54:20 +0000 (08:54 -0400)
committerMike Blumenkrantz <zmike@osg.samsung.com>
Thu, 23 Apr 2015 12:55:35 +0000 (08:55 -0400)
inotify reuses watches for multiple instances on the same file, so
keeping a multimap here is necessary to avoid hash collision

fix T2360

src/lib/ecore_file/ecore_file_monitor_inotify.c

index e6847ddb7b116a7c75fc37c0900f9bbfc06d64cb..f86b58d631b56c016d16cff5761f3499d6afe10c 100644 (file)
@@ -40,7 +40,7 @@ static Ecore_File_Monitor    *_monitors = NULL;
 static pid_t             _inotify_fd_pid = -1;
 
 static Eina_Bool           _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh);
-static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd);
+static Eina_List *_ecore_file_monitor_inotify_monitor_find(int wd);
 static void                _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask);
 static int                 _ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path);
 #if 0
@@ -144,7 +144,7 @@ ecore_file_monitor_backend_del(Ecore_File_Monitor *em)
    if (_monitors)
      _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
    if (ECORE_FILE_MONITOR_INOTIFY(em)->wd >= 0)
-     eina_hash_del_by_key(monitor_hash, &ECORE_FILE_MONITOR_INOTIFY(em)->wd);
+     eina_hash_list_remove(monitor_hash, &ECORE_FILE_MONITOR_INOTIFY(em)->wd, em);
 
    fd = ecore_main_fd_handler_fd_get(_fdh);
    if (ECORE_FILE_MONITOR_INOTIFY(em)->wd)
@@ -156,6 +156,7 @@ ecore_file_monitor_backend_del(Ecore_File_Monitor *em)
 static Eina_Bool
 _ecore_file_monitor_inotify_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh)
 {
+   Eina_List *l, *ll;
    Ecore_File_Monitor *em;
    char buffer[16384];
    struct inotify_event *event;
@@ -174,16 +175,15 @@ _ecore_file_monitor_inotify_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd
         if ((event_size + i) > size) break ;
         i += event_size;
 
-        em = _ecore_file_monitor_inotify_monitor_find(event->wd);
-        if (!em) continue;
-
-        _ecore_file_monitor_inotify_events(em, (event->len ? event->name : NULL), event->mask);
+        l = _ecore_file_monitor_inotify_monitor_find(event->wd);
+        EINA_LIST_FOREACH(l, ll, em)
+          _ecore_file_monitor_inotify_events(em, (event->len ? event->name : NULL), event->mask);
      }
 
    return ECORE_CALLBACK_RENEW;
 }
 
-static Ecore_File_Monitor *
+static Eina_List *
 _ecore_file_monitor_inotify_monitor_find(int wd)
 {
    return eina_hash_find(monitor_hash, &wd);
@@ -293,7 +293,7 @@ _ecore_file_monitor_inotify_monitor(Ecore_File_Monitor *em, const char *path)
         ecore_file_monitor_backend_del(em);
         return 0;
      }
-   eina_hash_add(monitor_hash, &ECORE_FILE_MONITOR_INOTIFY(em)->wd, em);
+   eina_hash_list_append(monitor_hash, &ECORE_FILE_MONITOR_INOTIFY(em)->wd, em);
    return 1;
 }