Prevent using freed data in epoll events
authorsachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 27 Jun 2012 19:01:16 +0000 (19:01 +0000)
committersachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 27 Jun 2012 19:01:16 +0000 (19:01 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@72960 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/evas_cserve2_main_loop_linux.c

index e8cc33d..6063925 100644 (file)
@@ -26,6 +26,7 @@ struct _Watch_Data
    Fd_Flags flags;
    Fd_Watch_Cb callback;
    const void *user_data;
+   Eina_Bool deleted : 1;
 };
 
 typedef struct _Watch_Data Watch_Data;
@@ -47,6 +48,7 @@ static int socket_fd = -1;
 static int inotify_fd = -1;
 static struct sockaddr_un socket_local;
 static Eina_Hash *watch_list;
+static Eina_List *deleted_watch_list;
 static Eina_Hash *inotify_path_hash;
 static Eina_Hash *inotify_id_hash;
 static Eina_Bool running;
@@ -354,7 +356,9 @@ _inotifyfd_finish(void)
 static void
 _watch_data_free_cb(void *data)
 {
-   free(data);
+   Watch_Data *wd = data;
+   wd->deleted = EINA_TRUE;
+   deleted_watch_list = eina_list_append(deleted_watch_list, wd);
 }
 
 Eina_Bool
@@ -444,6 +448,8 @@ error_socket:
 void
 cserve2_main_loop_finish(void)
 {
+   Watch_Data *wd;
+
    _socketfd_finish();
 
    _signalfd_finish();
@@ -451,6 +457,8 @@ cserve2_main_loop_finish(void)
    _inotifyfd_finish();
 
    eina_hash_free(watch_list);
+   EINA_LIST_FREE(deleted_watch_list, wd)
+     free(wd);
 
    close(epoll_fd);
 }
@@ -726,6 +734,7 @@ cserve2_main_loop_run(void)
      {
         struct epoll_event events[MAX_EPOLL_EVENTS];
         int n, nfds;
+        Watch_Data *data;
 
         if (terminate)
           break;
@@ -748,12 +757,15 @@ cserve2_main_loop_run(void)
 
         for (n = 0; n < nfds; n++)
           {
-             Watch_Data *data = events[n].data.ptr;
+             data = events[n].data.ptr;
              Fd_Flags flags = 0;
 
              if (!data)
                continue;
 
+             if (data->deleted)
+               continue;
+
              if (!data->callback)
                continue;
 
@@ -766,6 +778,9 @@ cserve2_main_loop_run(void)
              data->callback(data->fd, flags, (void *)data->user_data);
           }
 
+        EINA_LIST_FREE(deleted_watch_list, data)
+          free(data);
+
         _update_timeout();
      }