summaryrefslogtreecommitdiff
path: root/src/lib/eio
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2018-06-27 08:48:59 -0400
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2018-06-28 18:08:45 +0200
commitddc31e75ac68204a70784bce1516a5e38d426bf4 (patch)
tree91ff39f88143a5e428566b3de012a602db38bf01 /src/lib/eio
parent8a2a1c6488347ae26a28bac012c30b87f9b7d101 (diff)
eio/fallback: avoid emitting monitor events if the backend is pending deletion
emitting events if the delete_me flag is set may result in events being emitted for an already-freed monitor, resulting in both invalid memory access and a deadlock later on if eio_shutdown has been called at this point this causes the monitoring thread to check the status of the backend during the block where the main loop and thread are in sync, avoiding any data races which could occur when checking the flag at another time, and also avoiding accessing the internals of the Ecore_Thread which could also have been deallocated during shutdown fix T7086 Differential Revision: https://phab.enlightenment.org/D6449
Diffstat (limited to 'src/lib/eio')
-rw-r--r--src/lib/eio/eio_monitor_poll.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/lib/eio/eio_monitor_poll.c b/src/lib/eio/eio_monitor_poll.c
index 2133b3fe45..c7f208092c 100644
--- a/src/lib/eio/eio_monitor_poll.c
+++ b/src/lib/eio/eio_monitor_poll.c
@@ -66,6 +66,7 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
66 Eina_Stat *est; 66 Eina_Stat *est;
67 Eina_File_Direct_Info *info; 67 Eina_File_Direct_Info *info;
68 _eio_stat_t st; 68 _eio_stat_t st;
69 Eina_Bool deleted = EINA_FALSE;
69 /* FIXME : copy ecore_file_monitor_poll here */ 70 /* FIXME : copy ecore_file_monitor_poll here */
70 71
71 if (!backend->initialised) 72 if (!backend->initialised)
@@ -81,7 +82,9 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
81 if (backend->initialised && !backend->destroyed) 82 if (backend->initialised && !backend->destroyed)
82 { 83 {
83 ecore_thread_main_loop_begin(); 84 ecore_thread_main_loop_begin();
84 _eio_monitor_send(backend->parent, backend->parent->path, EIO_MONITOR_SELF_DELETED); 85 deleted = backend->delete_me;
86 if (!deleted)
87 _eio_monitor_send(backend->parent, backend->parent->path, EIO_MONITOR_SELF_DELETED);
85 ecore_thread_main_loop_end(); 88 ecore_thread_main_loop_end();
86 backend->destroyed = EINA_TRUE; 89 backend->destroyed = EINA_TRUE;
87 } 90 }
@@ -132,8 +135,11 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
132 /* regular file: eina_file_direct_ls will return NULL */ 135 /* regular file: eina_file_direct_ls will return NULL */
133 event = EIO_MONITOR_FILE_MODIFIED; 136 event = EIO_MONITOR_FILE_MODIFIED;
134 ecore_thread_main_loop_begin(); 137 ecore_thread_main_loop_begin();
135 _eio_monitor_send(backend->parent, backend->parent->path, event); 138 deleted = backend->delete_me;
139 if (!deleted)
140 _eio_monitor_send(backend->parent, backend->parent->path, event);
136 ecore_thread_main_loop_end(); 141 ecore_thread_main_loop_end();
142 if (deleted) return;
137 } 143 }
138 144
139 it = eina_file_direct_ls(backend->parent->path); 145 it = eina_file_direct_ls(backend->parent->path);
@@ -164,10 +170,12 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
164 { 170 {
165 /* New file or new directory added */ 171 /* New file or new directory added */
166 ecore_thread_main_loop_begin(); 172 ecore_thread_main_loop_begin();
167 _eio_monitor_send(backend->parent, info->path, 173 deleted = backend->delete_me;
168 info->type != EINA_FILE_DIR ? EIO_MONITOR_FILE_CREATED : EIO_MONITOR_DIRECTORY_CREATED); 174 if (!deleted)
175 _eio_monitor_send(backend->parent, info->path,
176 info->type != EINA_FILE_DIR ? EIO_MONITOR_FILE_CREATED : EIO_MONITOR_DIRECTORY_CREATED);
169 ecore_thread_main_loop_end(); 177 ecore_thread_main_loop_end();
170 178 if (deleted) break;
171 cmp = malloc(sizeof (Eio_Monitor_Stat)); 179 cmp = malloc(sizeof (Eio_Monitor_Stat));
172 memcpy(cmp, &buffer, sizeof (Eina_Stat)); 180 memcpy(cmp, &buffer, sizeof (Eina_Stat));
173 181
@@ -177,18 +185,20 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
177 { 185 {
178 /* file has been modified */ 186 /* file has been modified */
179 ecore_thread_main_loop_begin(); 187 ecore_thread_main_loop_begin();
180 _eio_monitor_send(backend->parent, info->path, 188 deleted = backend->delete_me;
181 info->type != EINA_FILE_DIR ? EIO_MONITOR_FILE_MODIFIED : EIO_MONITOR_DIRECTORY_MODIFIED); 189 if (!deleted)
190 _eio_monitor_send(backend->parent, info->path,
191 info->type != EINA_FILE_DIR ? EIO_MONITOR_FILE_MODIFIED : EIO_MONITOR_DIRECTORY_MODIFIED);
182 ecore_thread_main_loop_end(); 192 ecore_thread_main_loop_end();
183 193 if (deleted) break;
184 memcpy(cmp, &buffer, sizeof (Eina_Stat)); 194 memcpy(cmp, &buffer, sizeof (Eina_Stat));
185 } 195 }
186 } 196 }
187 197
188 cmp->version = backend->version; 198 cmp->version = backend->version;
189 if (ecore_thread_check(thread)) goto out; 199 if (ecore_thread_check(thread)) break;
190 } 200 }
191 out: 201
192 if (it) eina_iterator_free(it); 202 if (it) eina_iterator_free(it);
193 203
194 if (backend->initialised && !ecore_thread_check(thread)) 204 if (backend->initialised && !ecore_thread_check(thread))
@@ -206,6 +216,8 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
206 216
207 if (cmp->version != backend->version) 217 if (cmp->version != backend->version)
208 { 218 {
219 deleted = backend->delete_me;
220 if (deleted) break;
209 _eio_monitor_send(backend->parent, tuple->key, 221 _eio_monitor_send(backend->parent, tuple->key,
210 eio_file_is_dir(&cmp->buffer) ? EIO_MONITOR_DIRECTORY_DELETED : EIO_MONITOR_FILE_DELETED); 222 eio_file_is_dir(&cmp->buffer) ? EIO_MONITOR_DIRECTORY_DELETED : EIO_MONITOR_FILE_DELETED);
211 eina_array_push(arr, tuple->key); 223 eina_array_push(arr, tuple->key);