summaryrefslogtreecommitdiff
path: root/src/lib/eio
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2019-03-15 14:38:24 -0700
committerCedric BAIL <cedric.bail@free.fr>2019-03-27 15:03:33 -0700
commit150bc0fa14d7df39254173980de5c86085b1ceff (patch)
tree7ea12ae2f7821a36185ad7ae43a3da2c095b7b92 /src/lib/eio
parente162ba9696cb25ad91b44649da00dd942c2a5236 (diff)
eio: work around the lack of integration between Ecore_Thread and Eina_Future.
Ecore_Thread excpect resolution of the error and done case to be instantaneous, while Eina_Future default scheduler linked with Ecore main loop is build around asynchronous answer. This create a lot of potential. A better patch would be to provide an Ecore_Thread helper that does the integration properly. Sadly we are in release now, so this is basically what an helper would do, but contained inside Efl_Io_Manager. This also solve the same problem as D7970 and D8053, but it should avoid its side effect. Reviewed-by: YeongJong Lee <yj34.lee@samsung.com> Differential Revision: https://phab.enlightenment.org/D8371
Diffstat (limited to 'src/lib/eio')
-rw-r--r--src/lib/eio/efl_io_manager.c120
1 files changed, 111 insertions, 9 deletions
diff --git a/src/lib/eio/efl_io_manager.c b/src/lib/eio/efl_io_manager.c
index 3509bc6..3bb0563 100644
--- a/src/lib/eio/efl_io_manager.c
+++ b/src/lib/eio/efl_io_manager.c
@@ -49,6 +49,102 @@ struct _Job_Closure
49 Efl_Io_Manager_Direct_Ls_Func direct_func; // Used when dispatching direct ls funcs. 49 Efl_Io_Manager_Direct_Ls_Func direct_func; // Used when dispatching direct ls funcs.
50}; 50};
51 51
52/* Future have to be resolved right away in the thread context */
53typedef struct _Eio_Future_Entry Eio_Future_Entry;
54struct _Eio_Future_Entry
55{
56 Eina_Future_Schedule_Entry base;
57 Eina_Future_Scheduler_Cb cb;
58 Eina_Future *future;
59 Eina_Value value;
60};
61
62static Eina_Trash *eio_entry_trash = NULL;
63static unsigned int eio_entry_trash_count = 0;
64static Eina_List *entries = NULL;
65
66static Eina_Future_Schedule_Entry *
67eio_future_schedule(Eina_Future_Scheduler *sched,
68 Eina_Future_Scheduler_Cb cb,
69 Eina_Future *future,
70 Eina_Value value)
71{
72 Eio_Future_Entry *ef = NULL;
73
74 if (!eio_entry_trash)
75 {
76 ef = calloc(1, sizeof (Eio_Future_Entry));
77 if (!ef) return NULL;
78 }
79 else
80 {
81 ef = eina_trash_pop(&eio_entry_trash);
82 eio_entry_trash_count--;
83 }
84 ef->base.scheduler = sched;
85 ef->cb = cb;
86 ef->future = future;
87 ef->value = value;
88
89 entries = eina_list_append(entries, ef);
90
91 return &ef->base;
92}
93
94static void
95eio_future_free(Eio_Future_Entry *ef)
96{
97 entries = eina_list_remove(entries, ef);
98
99 if (eio_entry_trash_count > 8)
100 {
101 free(ef);
102 return ;
103 }
104 eina_trash_push(&eio_entry_trash, ef);
105 eio_entry_trash_count++;
106}
107
108static void
109eio_future_recall(Eina_Future_Schedule_Entry *se)
110{
111 Eio_Future_Entry *ef = (Eio_Future_Entry *) se;
112
113 eina_value_flush(&ef->value);
114 eio_future_free(ef);
115}
116
117static Eina_Future_Scheduler eio_future_scheduler = {
118 .schedule = eio_future_schedule,
119 .recall = eio_future_recall,
120};
121
122static void
123eio_dummy_cancel(void *data EINA_UNUSED, const Eina_Promise *p EINA_UNUSED)
124{
125}
126
127static void
128eio_process_entry(void)
129{
130 Eio_Future_Entry *ef;
131
132 while (entries)
133 {
134 ef = eina_list_data_get(entries);
135 ef->cb(ef->future, ef->value);
136 eio_future_free(ef);
137 }
138}
139
140static Eina_Promise *
141eio_promise_new(const Eo *obj)
142{
143 if (!efl_alive_get(obj)) return NULL;
144
145 return eina_promise_new(&eio_future_scheduler, eio_dummy_cancel, NULL);
146}
147
52/* Helper functions */ 148/* Helper functions */
53static void 149static void
54_future_file_done_cb(void *data, Eio_File *handler) 150_future_file_done_cb(void *data, Eio_File *handler)
@@ -56,6 +152,7 @@ _future_file_done_cb(void *data, Eio_File *handler)
56 Eina_Promise *p = data; 152 Eina_Promise *p = data;
57 153
58 eina_promise_resolve(p, eina_value_uint64_init(handler->length)); 154 eina_promise_resolve(p, eina_value_uint64_init(handler->length));
155 eio_process_entry();
59} 156}
60 157
61static void 158static void
@@ -67,6 +164,7 @@ _future_file_error_cb(void *data,
67 164
68 // error == 0 -> promise was cancelled, no need to reject it anymore 165 // error == 0 -> promise was cancelled, no need to reject it anymore
69 if (error != 0) eina_promise_reject(p, error); 166 if (error != 0) eina_promise_reject(p, error);
167 eio_process_entry();
70} 168}
71 169
72/* Basic listing callbacks */ 170/* Basic listing callbacks */
@@ -119,7 +217,7 @@ _efl_io_manager_direct_ls(const Eo *obj,
119 Eina_Future *future; 217 Eina_Future *future;
120 Eio_File *h; 218 Eio_File *h;
121 219
122 p = efl_loop_promise_new(obj); 220 p = eio_promise_new(obj);
123 if (!p) return NULL; 221 if (!p) return NULL;
124 future = eina_future_new(p); 222 future = eina_future_new(p);
125 223
@@ -161,7 +259,7 @@ _efl_io_manager_stat_ls(const Eo *obj,
161 Eina_Future *future; 259 Eina_Future *future;
162 Eio_File *h; 260 Eio_File *h;
163 261
164 p = efl_loop_promise_new(obj); 262 p = eio_promise_new(obj);
165 if (!p) return NULL; 263 if (!p) return NULL;
166 future = eina_future_new(p); 264 future = eina_future_new(p);
167 265
@@ -202,7 +300,7 @@ _efl_io_manager_ls(const Eo *obj,
202 Eina_Future *future; 300 Eina_Future *future;
203 Eio_File *h; 301 Eio_File *h;
204 302
205 p = efl_loop_promise_new(obj); 303 p = eio_promise_new(obj);
206 if (!p) return NULL; 304 if (!p) return NULL;
207 future = eina_future_new(p); 305 future = eina_future_new(p);
208 306
@@ -236,12 +334,14 @@ _file_stat_done_cb(void *data, Eio_File *handle EINA_UNUSED, const Eina_Stat *st
236 goto on_error; 334 goto on_error;
237 335
238 eina_promise_resolve(p, r); 336 eina_promise_resolve(p, r);
337 eio_process_entry();
239 338
240 return ; 339 return ;
241 340
242 on_error: 341 on_error:
243 eina_value_flush(&r); 342 eina_value_flush(&r);
244 eina_promise_reject(p, eina_error_get()); 343 eina_promise_reject(p, eina_error_get());
344 eio_process_entry();
245} 345}
246 346
247static Eina_Future * 347static Eina_Future *
@@ -253,7 +353,7 @@ _efl_io_manager_stat(const Eo *obj,
253 Eina_Future *future; 353 Eina_Future *future;
254 Eio_File *h; 354 Eio_File *h;
255 355
256 p = efl_loop_promise_new(obj); 356 p = eio_promise_new(obj);
257 if (!p) return NULL; 357 if (!p) return NULL;
258 future = eina_future_new(p); 358 future = eina_future_new(p);
259 359
@@ -281,7 +381,7 @@ _efl_io_manager_xattr_ls(const Eo *obj,
281 Eina_Future *future; 381 Eina_Future *future;
282 Eio_File *h; 382 Eio_File *h;
283 383
284 p = efl_loop_promise_new(obj); 384 p = eio_promise_new(obj);
285 if (!p) return NULL; 385 if (!p) return NULL;
286 future = eina_future_new(p); 386 future = eina_future_new(p);
287 387
@@ -317,6 +417,7 @@ _future_file_done_data_cb(void *data, Eio_File *handler EINA_UNUSED, const char
317 eina_value_setup(&v, EINA_VALUE_TYPE_BLOB); 417 eina_value_setup(&v, EINA_VALUE_TYPE_BLOB);
318 eina_value_set(&v, &blob); 418 eina_value_set(&v, &blob);
319 eina_promise_resolve(p, v); 419 eina_promise_resolve(p, v);
420 eio_process_entry();
320} 421}
321 422
322static Eina_Future * 423static Eina_Future *
@@ -331,7 +432,7 @@ _efl_io_manager_xattr_set(Eo *obj,
331 Eina_Future *future; 432 Eina_Future *future;
332 Eio_File *h; 433 Eio_File *h;
333 434
334 p = efl_loop_promise_new(obj); 435 p = eio_promise_new(obj);
335 if (!p) return NULL; 436 if (!p) return NULL;
336 future = eina_future_new(p); 437 future = eina_future_new(p);
337 438
@@ -360,7 +461,7 @@ _efl_io_manager_xattr_get(const Eo *obj,
360 Eina_Future *future; 461 Eina_Future *future;
361 Eio_File *h; 462 Eio_File *h;
362 463
363 p = efl_loop_promise_new(obj); 464 p = eio_promise_new(obj);
364 if (!p) return NULL; 465 if (!p) return NULL;
365 future = eina_future_new(p); 466 future = eina_future_new(p);
366 467
@@ -385,6 +486,7 @@ _future_file_open_cb(void *data, Eio_File *handler EINA_UNUSED, Eina_File *file)
385 eina_value_setup(&v, EINA_VALUE_TYPE_FILE); 486 eina_value_setup(&v, EINA_VALUE_TYPE_FILE);
386 eina_value_set(&v, file); 487 eina_value_set(&v, file);
387 eina_promise_resolve(p, v); 488 eina_promise_resolve(p, v);
489 eio_process_entry();
388} 490}
389 491
390static Eina_Future * 492static Eina_Future *
@@ -397,7 +499,7 @@ _efl_io_manager_open(const Eo *obj,
397 Eina_Future *future; 499 Eina_Future *future;
398 Eio_File *h; 500 Eio_File *h;
399 501
400 p = efl_loop_promise_new(obj); 502 p = eio_promise_new(obj);
401 if (!p) return NULL; 503 if (!p) return NULL;
402 future = eina_future_new(p); 504 future = eina_future_new(p);
403 505
@@ -422,7 +524,7 @@ _efl_io_manager_close(const Eo *obj,
422 Eina_Future *future; 524 Eina_Future *future;
423 Eio_File *h; 525 Eio_File *h;
424 526
425 p = efl_loop_promise_new(obj); 527 p = eio_promise_new(obj);
426 if (!p) return NULL; 528 if (!p) return NULL;
427 future = eina_future_new(p); 529 future = eina_future_new(p);
428 530