Changeset View
Changeset View
Standalone View
Standalone View
src/lib/eio/efl_io_model.c
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Line(s) | 66 | { | |||
---|---|---|---|---|---|
95 | mi = calloc(1, sizeof (Efl_Io_Model_Info)); | 95 | mi = calloc(1, sizeof (Efl_Io_Model_Info)); | ||
96 | if (!mi) goto end; | 96 | if (!mi) goto end; | ||
97 | 97 | | |||
98 | mi->path_length = eina_stringshare_strlen(spath); | 98 | mi->path_length = eina_stringshare_strlen(spath); | ||
99 | mi->path = eina_stringshare_ref(spath); | 99 | mi->path = eina_stringshare_ref(spath); | ||
100 | mi->name_start = eina_stringshare_strlen(pd->path) + 1; | 100 | mi->name_start = eina_stringshare_strlen(pd->path) + 1; | ||
101 | mi->name_length = mi->path_length - mi->name_start; | 101 | mi->name_length = mi->path_length - mi->name_start; | ||
102 | mi->type = EINA_FILE_UNKNOWN; | 102 | mi->type = EINA_FILE_UNKNOWN; | ||
103 | mi->parent_ref = EINA_TRUE; | 103 | mi->parent_ref = EINA_FALSE; | ||
104 | mi->child_ref = EINA_TRUE; | ||||
104 | 105 | | |||
105 | // Honor filter on new added file too | 106 | // Honor filter on new added file too | ||
106 | if (pd->filter.cb) | 107 | if (pd->filter.cb) | ||
107 | { | 108 | { | ||
108 | Eina_File_Direct_Info info = { 0 }; | 109 | Eina_File_Direct_Info info = { 0 }; | ||
109 | 110 | | |||
110 | info.path_length = mi->path_length; | 111 | info.path_length = mi->path_length; | ||
111 | info.name_start = mi->name_start; | 112 | info.name_start = mi->name_start; | ||
112 | info.name_length = mi->name_length; | 113 | info.name_length = mi->name_length; | ||
113 | info.type = EINA_FILE_UNKNOWN; | 114 | info.type = EINA_FILE_UNKNOWN; | ||
114 | strncpy(info.path, mi->path, (EINA_PATH_MAX - 1)); | 115 | strncpy(info.path, mi->path, (EINA_PATH_MAX - 1)); | ||
115 | 116 | | |||
116 | if (!pd->filter.cb(pd->filter.data, obj, &info)) | 117 | if (!pd->filter.cb(pd->filter.data, obj, &info)) | ||
117 | { | 118 | { | ||
118 | eina_stringshare_del(mi->path); | 119 | eina_stringshare_replace(&mi->path, NULL); | ||
zmike: ? | |||||
Not Done ReplyI find it a better practice to always use replace and make all the pointer NULL before calling free. Avoid access to dead pointer and weird stuff happening. cedric: I find it a better practice to always use replace and make all the pointer NULL before calling… | |||||
119 | free(mi); | 120 | free(mi); | ||
120 | goto end; | 121 | goto end; | ||
121 | } | 122 | } | ||
122 | } | 123 | } | ||
123 | 124 | | |||
124 | cevt.index = eina_list_count(pd->files); | 125 | cevt.index = eina_list_count(pd->files); | ||
125 | pd->files = eina_list_append(pd->files, mi); | 126 | pd->files = eina_list_append(pd->files, mi); | ||
126 | 127 | | |||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 141 | { | |||
171 | cevt.child = mi->object; | 172 | cevt.child = mi->object; | ||
172 | 173 | | |||
173 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_REMOVED, &cevt); | 174 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_REMOVED, &cevt); | ||
174 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL); | 175 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL); | ||
175 | 176 | | |||
176 | // Remove the entry from the files list | 177 | // Remove the entry from the files list | ||
177 | pd->files = eina_list_remove_list(pd->files, l); | 178 | pd->files = eina_list_remove_list(pd->files, l); | ||
178 | 179 | | |||
179 | // This should trigger the object child destruction if it exist | 180 | // This will only trigger the data destruction if no object is referencing them. | ||
180 | // resulting in the potential destruction of the child, after | | |||
181 | // this point mi and info might be freed. | | |||
182 | _efl_io_model_info_free(mi, EINA_FALSE); | 181 | _efl_io_model_info_free(mi, EINA_FALSE); | ||
183 | 182 | | |||
184 | end: | 183 | end: | ||
185 | eina_stringshare_del(spath); | 184 | eina_stringshare_del(spath); | ||
186 | 185 | | |||
187 | return EINA_TRUE; | 186 | return EINA_TRUE; | ||
188 | } | 187 | } | ||
189 | 188 | | |||
Show All 30 Lines | |||||
220 | 219 | | |||
221 | static void | 220 | static void | ||
222 | _efl_io_model_info_free(Efl_Io_Model_Info *info, Eina_Bool model) | 221 | _efl_io_model_info_free(Efl_Io_Model_Info *info, Eina_Bool model) | ||
223 | { | 222 | { | ||
224 | if (!info) return ; | 223 | if (!info) return ; | ||
225 | 224 | | |||
226 | if (!model) | 225 | if (!model) | ||
227 | { | 226 | { | ||
228 | if (!info->object) | | |||
229 | { | | |||
230 | efl_del(info->object); | | |||
231 | info->object = NULL; | | |||
232 | } | | |||
233 | info->child_ref = EINA_FALSE; | 227 | info->child_ref = EINA_FALSE; | ||
234 | } | 228 | } | ||
235 | else | 229 | else | ||
236 | { | 230 | { | ||
237 | info->parent_ref = EINA_FALSE; | 231 | info->parent_ref = EINA_FALSE; | ||
238 | } | 232 | } | ||
239 | 233 | | |||
240 | if (info->child_ref || | 234 | if (info->child_ref || | ||
241 | info->parent_ref) | 235 | info->parent_ref) | ||
242 | return ; | 236 | return ; | ||
243 | 237 | | |||
244 | eina_stringshare_del(info->path); | 238 | eina_stringshare_replace(&info->path, NULL); | ||
Not Done Reply? zmike: ? | |||||
245 | free(info); | 239 | free(info); | ||
246 | } | 240 | } | ||
247 | 241 | | |||
248 | static Eina_File_Type | 242 | static Eina_File_Type | ||
249 | _efl_io_model_info_type_get(const Eina_File_Direct_Info *info, const Eina_Stat *st) | 243 | _efl_io_model_info_type_get(const Eina_File_Direct_Info *info, const Eina_Stat *st) | ||
250 | { | 244 | { | ||
251 | if (info && info->type != EINA_FILE_UNKNOWN) | 245 | if (info && info->type != EINA_FILE_UNKNOWN) | ||
252 | return info->type; | 246 | return info->type; | ||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | |||||
331 | } | 325 | } | ||
332 | 326 | | |||
333 | static void | 327 | static void | ||
334 | _eio_build_st_done_clobber(void *data, Eio_File *handler, const Eina_Stat *stat) | 328 | _eio_build_st_done_clobber(void *data, Eio_File *handler, const Eina_Stat *stat) | ||
335 | { | 329 | { | ||
336 | Efl_Io_Model *model = data; | 330 | Efl_Io_Model *model = data; | ||
337 | Efl_Io_Model *parent; | 331 | Efl_Io_Model *parent; | ||
338 | 332 | | |||
339 | efl_ref(model); | 333 | efl_ref(model); // For st_done | ||
340 | _eio_build_st_done(data, handler, stat); | 334 | _eio_build_st_done(data, handler, stat); | ||
341 | parent = efl_parent_get(model); | 335 | parent = efl_parent_get(model); | ||
342 | efl_model_child_del(parent, model); | 336 | efl_model_child_del(parent, model); | ||
343 | efl_unref(model); | 337 | efl_unref(model); // From the async thread early ref | ||
344 | } | 338 | } | ||
345 | 339 | | |||
346 | static void | 340 | static void | ||
347 | _eio_build_st_error(void *data, Eio_File *handler EINA_UNUSED, int error) | 341 | _eio_build_st_error(void *data, Eio_File *handler EINA_UNUSED, int error) | ||
348 | { | 342 | { | ||
349 | Efl_Io_Model *model = data; | 343 | Efl_Io_Model *model = data; | ||
350 | Efl_Io_Model_Data *pd = efl_data_scope_get(model, EFL_IO_MODEL_CLASS); | 344 | Efl_Io_Model_Data *pd = efl_data_scope_get(model, EFL_IO_MODEL_CLASS); | ||
351 | 345 | | |||
352 | pd->request.stat = NULL; | 346 | pd->request.stat = NULL; | ||
353 | pd->error = error; | 347 | pd->error = error; | ||
354 | 348 | | |||
355 | efl_model_properties_changed(model, "direct_info", "mtime", "atime", "ctime", "is_dir", "is_lnk", "size", "stat"); | 349 | efl_model_properties_changed(model, "direct_info", "mtime", "atime", "ctime", "is_dir", "is_lnk", "size", "stat"); | ||
356 | 350 | | |||
357 | efl_unref(model); | 351 | efl_unref(model); | ||
358 | } | 352 | } | ||
359 | 353 | | |||
360 | static void | 354 | static void | ||
361 | _eio_build_st_error_clobber(void *data, Eio_File *handler, int error) | 355 | _eio_build_st_error_clobber(void *data, Eio_File *handler, int error) | ||
362 | { | 356 | { | ||
363 | Efl_Io_Model *model = data; | 357 | Efl_Io_Model *model = data; | ||
364 | Efl_Io_Model *parent; | | |||
365 | 358 | | |||
366 | efl_ref(model); | 359 | efl_ref(model); // For st_error unref | ||
367 | _eio_build_st_error(data, handler, error); | 360 | _eio_build_st_error(data, handler, error); | ||
368 | parent = efl_parent_get(model); | 361 | efl_unref(model); // From the async thread early ref | ||
369 | efl_model_child_del(parent, model); | | |||
370 | efl_unref(model); | | |||
371 | } | 362 | } | ||
372 | 363 | | |||
373 | static void | 364 | static void | ||
374 | _eio_build_st(const Efl_Io_Model *model, Efl_Io_Model_Data *pd) | 365 | _eio_build_st(const Efl_Io_Model *model, Efl_Io_Model_Data *pd) | ||
375 | { | 366 | { | ||
376 | if (pd->st) return ; | 367 | if (pd->st) return ; | ||
377 | if (pd->request.stat) return ; | 368 | if (pd->request.stat) return ; | ||
378 | if (pd->error) return ; | 369 | if (pd->error) return ; | ||
379 | 370 | | |||
380 | pd->request.stat = eio_file_direct_stat(pd->path, _eio_build_st_done, _eio_build_st_error, efl_ref(model)); | 371 | pd->request.stat = eio_file_direct_stat(pd->path, | ||
372 | _eio_build_st_done, | ||||
373 | _eio_build_st_error, | ||||
374 | efl_ref(model)); | ||||
381 | } | 375 | } | ||
382 | 376 | | |||
383 | static void | 377 | static void | ||
384 | _eio_build_st_then_clobber(const Efl_Io_Model *model, Efl_Io_Model_Data *pd) | 378 | _eio_build_st_then_clobber(const Efl_Io_Model *model, Efl_Io_Model_Data *pd) | ||
385 | { | 379 | { | ||
386 | if (pd->st) return ; | 380 | if (pd->st) return ; | ||
387 | if (pd->request.stat) return ; | 381 | if (pd->request.stat) return ; | ||
388 | if (pd->error) return ; | 382 | if (pd->error) return ; | ||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Line(s) | 489 | { | |||
497 | if (pd->info) | 491 | if (pd->info) | ||
498 | return eina_value_string_new(pd->info->path + pd->info->name_start); | 492 | return eina_value_string_new(pd->info->path + pd->info->name_start); | ||
499 | return eina_value_error_new(EAGAIN); | 493 | return eina_value_error_new(EAGAIN); | ||
500 | } | 494 | } | ||
501 | 495 | | |||
502 | static Eina_Value * | 496 | static Eina_Value * | ||
503 | _property_path_cb(const Eo *obj EINA_UNUSED, Efl_Io_Model_Data *pd) | 497 | _property_path_cb(const Eo *obj EINA_UNUSED, Efl_Io_Model_Data *pd) | ||
504 | { | 498 | { | ||
505 | return eina_value_string_new(pd->path); | 499 | return eina_value_stringshare_new(pd->path); | ||
506 | } | 500 | } | ||
507 | 501 | | |||
508 | static Eina_Value * | 502 | static Eina_Value * | ||
509 | _property_direct_info_cb(const Eo *obj, Efl_Io_Model_Data *pd) | 503 | _property_direct_info_cb(const Eo *obj, Efl_Io_Model_Data *pd) | ||
510 | { | 504 | { | ||
511 | _efl_io_model_info_build(obj, pd); | 505 | _efl_io_model_info_build(obj, pd); | ||
512 | 506 | | |||
513 | if (pd->info) | 507 | if (pd->info) | ||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Line(s) | 681 | { | |||
695 | ecore_thread_local_data_add(pd->request.move->thread, ".pd", pd, NULL, EINA_TRUE); | 689 | ecore_thread_local_data_add(pd->request.move->thread, ".pd", pd, NULL, EINA_TRUE); | ||
696 | 690 | | |||
697 | f = _efl_io_manager_future(obj, f, pd->request.move); | 691 | f = _efl_io_manager_future(obj, f, pd->request.move); | ||
698 | 692 | | |||
699 | // FIXME: turn on monitor in the finalize stage or after move | 693 | // FIXME: turn on monitor in the finalize stage or after move | ||
700 | } | 694 | } | ||
701 | else | 695 | else | ||
702 | { | 696 | { | ||
703 | f = efl_loop_future_resolved(obj, eina_value_string_init(pd->path)); | 697 | f = efl_loop_future_resolved(obj, eina_value_stringshare_init(pd->path)); | ||
704 | } | 698 | } | ||
705 | 699 | | |||
706 | return f; | 700 | return f; | ||
707 | 701 | | |||
708 | on_error: | 702 | on_error: | ||
709 | return efl_loop_future_rejected(obj, err); | 703 | return efl_loop_future_rejected(obj, err); | ||
710 | } | 704 | } | ||
711 | 705 | | |||
Show All 24 Lines | 720 | { | |||
736 | if (!mi) continue ; | 730 | if (!mi) continue ; | ||
737 | 731 | | |||
738 | mi->path_length = info->path_length; | 732 | mi->path_length = info->path_length; | ||
739 | mi->path = eina_stringshare_add(info->path); | 733 | mi->path = eina_stringshare_add(info->path); | ||
740 | 734 | | |||
741 | mi->name_start = info->name_start; | 735 | mi->name_start = info->name_start; | ||
742 | mi->name_length = info->name_length; | 736 | mi->name_length = info->name_length; | ||
743 | mi->type = _efl_io_model_info_type_get(info, NULL); | 737 | mi->type = _efl_io_model_info_type_get(info, NULL); | ||
744 | mi->parent_ref = EINA_TRUE; | 738 | mi->parent_ref = EINA_FALSE; | ||
739 | mi->child_ref = EINA_TRUE; | ||||
745 | 740 | | |||
746 | cevt.index = eina_list_count(pd->files); | 741 | cevt.index = eina_list_count(pd->files); | ||
747 | cevt.child = NULL; | 742 | cevt.child = NULL; | ||
748 | 743 | | |||
749 | pd->files = eina_list_append(pd->files, mi); | 744 | pd->files = eina_list_append(pd->files, mi); | ||
750 | 745 | | |||
751 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt); | 746 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt); | ||
752 | } | 747 | } | ||
753 | 748 | | |||
754 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL); | 749 | efl_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, NULL); | ||
755 | } | 750 | } | ||
756 | 751 | | |||
757 | static Eina_Value | 752 | static Eina_Value | ||
758 | _efl_io_model_children_list_on(void *data, const Eina_Value v, | 753 | _efl_io_model_children_list_on(Eo *o EINA_UNUSED, void *data, const Eina_Value v) | ||
759 | const Eina_Future *dead EINA_UNUSED) | | |||
760 | { | 754 | { | ||
761 | Efl_Io_Model_Data *pd = data; | 755 | Efl_Io_Model_Data *pd = data; | ||
762 | 756 | | |||
763 | pd->request.listing = NULL; | | |||
764 | pd->listed = EINA_TRUE; | | |||
765 | | ||||
766 | // Now that we have listed the content of the directory, | 757 | // Now that we have listed the content of the directory, | ||
767 | // we can whatch over it | 758 | // we can whatch over it | ||
768 | _efl_io_model_efl_model_monitor_add(pd); | 759 | _efl_io_model_efl_model_monitor_add(pd); | ||
769 | 760 | | |||
770 | return v; | 761 | return v; | ||
771 | } | 762 | } | ||
772 | 763 | | |||
764 | static void | ||||
765 | _efl_io_model_children_list_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED) | ||||
766 | { | ||||
767 | Efl_Io_Model_Data *pd = data; | ||||
768 | | ||||
769 | pd->request.listing = NULL; | ||||
770 | pd->listed = EINA_TRUE; | ||||
771 | } | ||||
772 | | ||||
773 | /** | 773 | /** | ||
774 | * Children Count Get | 774 | * Children Count Get | ||
775 | */ | 775 | */ | ||
776 | static unsigned int | 776 | static unsigned int | ||
777 | _efl_io_model_efl_model_children_count_get(const Eo *obj, Efl_Io_Model_Data *pd) | 777 | _efl_io_model_efl_model_children_count_get(const Eo *obj, Efl_Io_Model_Data *pd) | ||
778 | { | 778 | { | ||
779 | // If we have no information on the object, let's build it. | 779 | // If we have no information on the object, let's build it. | ||
780 | if (efl_invalidated_get(obj)) | 780 | if (efl_invalidated_get(obj)) | ||
Show All 15 Lines | 791 | { | |||
796 | if (!iom) | 796 | if (!iom) | ||
797 | { | 797 | { | ||
798 | ERR("Could not find an Efl.Io.Manager on %p.", obj); | 798 | ERR("Could not find an Efl.Io.Manager on %p.", obj); | ||
799 | return 0; | 799 | return 0; | ||
800 | } | 800 | } | ||
801 | 801 | | |||
802 | f = efl_io_manager_direct_ls(iom, pd->path, EINA_FALSE, | 802 | f = efl_io_manager_direct_ls(iom, pd->path, EINA_FALSE, | ||
803 | (void*) obj, _efl_io_model_children_list, NULL); | 803 | (void*) obj, _efl_io_model_children_list, NULL); | ||
804 | f = eina_future_then(f, _efl_io_model_children_list_on, pd, NULL); | 804 | | ||
805 | pd->request.listing = efl_future_then(obj, f); | 805 | pd->request.listing = efl_future_then(obj, f, | ||
806 | .success = _efl_io_model_children_list_on, | ||||
807 | .free = _efl_io_model_children_list_cleanup, | ||||
808 | .data = pd); | ||||
806 | } | 809 | } | ||
807 | 810 | | |||
808 | return eina_list_count(pd->files); | 811 | return eina_list_count(pd->files); | ||
809 | } | 812 | } | ||
810 | 813 | | |||
811 | static void | 814 | static void | ||
812 | _efl_io_model_efl_model_monitor_add(Efl_Io_Model_Data *priv) | 815 | _efl_io_model_efl_model_monitor_add(Efl_Io_Model_Data *priv) | ||
813 | { | 816 | { | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | |||||
873 | _efl_io_model_efl_model_child_del(Eo *obj EINA_UNUSED, | 876 | _efl_io_model_efl_model_child_del(Eo *obj EINA_UNUSED, | ||
874 | Efl_Io_Model_Data *priv EINA_UNUSED, | 877 | Efl_Io_Model_Data *priv EINA_UNUSED, | ||
875 | Eo *child) | 878 | Eo *child) | ||
876 | { | 879 | { | ||
877 | Efl_Io_Model_Data *child_pd; | 880 | Efl_Io_Model_Data *child_pd; | ||
878 | Eina_File_Type type; | 881 | Eina_File_Type type; | ||
879 | 882 | | |||
880 | child_pd = efl_data_scope_get(child, MY_CLASS); | 883 | child_pd = efl_data_scope_get(child, MY_CLASS); | ||
881 | if (!child_pd->info) goto on_error; | 884 | if (!child_pd->info) return; | ||
882 | if (child_pd->error) goto on_error; | 885 | if (child_pd->error) return; | ||
883 | 886 | | |||
884 | type = child_pd->info->type; | 887 | type = child_pd->info->type; | ||
885 | 888 | | |||
886 | if (type == EINA_FILE_UNKNOWN) | 889 | if (type == EINA_FILE_UNKNOWN) | ||
887 | { | 890 | { | ||
888 | _eio_build_st_then_clobber(child, child_pd); | 891 | _eio_build_st_then_clobber(child, child_pd); | ||
889 | return ; | 892 | return ; | ||
890 | } | 893 | } | ||
891 | 894 | | |||
895 | // Already in progress | ||||
896 | if (child_pd->request.del) return; | ||||
897 | | ||||
892 | efl_ref(child); | 898 | efl_ref(child); | ||
893 | if (type == EINA_FILE_DIR) | 899 | if (type == EINA_FILE_DIR) | ||
894 | { | 900 | { | ||
895 | child_pd->request.del = eio_dir_unlink(child_pd->path, | 901 | child_pd->request.del = eio_dir_unlink(child_pd->path, | ||
896 | NULL, | 902 | NULL, | ||
897 | NULL, | 903 | NULL, | ||
898 | _eio_done_unlink_cb, | 904 | _eio_done_unlink_cb, | ||
899 | _eio_error_unlink_cb, | 905 | _eio_error_unlink_cb, | ||
900 | child); | 906 | child); | ||
901 | } | 907 | } | ||
902 | else | 908 | else | ||
903 | { | 909 | { | ||
904 | child_pd->request.del = eio_file_unlink(child_pd->path, | 910 | child_pd->request.del = eio_file_unlink(child_pd->path, | ||
905 | _eio_done_unlink_cb, | 911 | _eio_done_unlink_cb, | ||
906 | _eio_error_unlink_cb, | 912 | _eio_error_unlink_cb, | ||
907 | child); | 913 | child); | ||
908 | } | 914 | } | ||
909 | | ||||
910 | return ; | | |||
911 | | ||||
912 | on_error: | | |||
913 | efl_del(child); | | |||
914 | } | 915 | } | ||
Not Done Reply? zmike: ? | |||||
Not Done ReplyIt was a misunderstanding of the API to think that child del was a synonym to efl_del, but it is not. It implies to destroy the underlying data that the model represent it. While efl_del imply only destroying the model. cedric: It was a misunderstanding of the API to think that child del was a synonym to efl_del, but it… | |||||
Not Done ReplyOh okay. In that case, I was wondering why you had a return here for a void function? zmike: Oh okay. In that case, I was wondering why you had a return here for a void function? | |||||
915 | 916 | | |||
916 | /** | 917 | /** | ||
917 | * Children Slice Get | 918 | * Children Slice Get | ||
918 | */ | 919 | */ | ||
919 | static Eina_Future * | 920 | static Eina_Future * | ||
920 | _efl_io_model_efl_model_children_slice_get(Eo *obj, Efl_Io_Model_Data *pd, | 921 | _efl_io_model_efl_model_children_slice_get(Eo *obj, Efl_Io_Model_Data *pd, | ||
921 | unsigned int start, unsigned int count) | 922 | unsigned int start, unsigned int count) | ||
922 | { | 923 | { | ||
Show All 19 Lines | |||||
942 | 943 | | |||
943 | ls = eina_list_nth_list(pd->files, start); | 944 | ls = eina_list_nth_list(pd->files, start); | ||
944 | 945 | | |||
945 | while (count > 0) | 946 | while (count > 0) | ||
946 | { | 947 | { | ||
947 | Efl_Io_Model_Info *info = eina_list_data_get(ls); | 948 | Efl_Io_Model_Info *info = eina_list_data_get(ls); | ||
948 | Efl_Io_Model_Data *child_data = NULL; | 949 | Efl_Io_Model_Data *child_data = NULL; | ||
949 | 950 | | |||
950 | info->child_ref = EINA_TRUE; | 951 | info->parent_ref = EINA_TRUE; | ||
951 | 952 | | |||
952 | if (info->object == NULL) | 953 | if (info->object == NULL) | ||
953 | // Little trick here, setting internal data before finalize | 954 | // Little trick here, setting internal data before finalize | ||
954 | info->object = efl_add(EFL_IO_MODEL_CLASS, obj, | 955 | info->object = efl_add_ref(EFL_IO_MODEL_CLASS, obj, | ||
955 | child_data = efl_data_scope_get(efl_added, EFL_IO_MODEL_CLASS), | 956 | efl_loop_model_volatile_make(efl_added), | ||
956 | child_data->info = info, | 957 | child_data = efl_data_scope_get(efl_added, EFL_IO_MODEL_CLASS), | ||
957 | child_data->path = eina_stringshare_ref(info->path), | 958 | child_data->info = info, | ||
958 | child_data->parent = ls, | 959 | child_data->path = eina_stringshare_ref(info->path), | ||
959 | // NOTE: We are assuming here that the parent model will outlive all its children | 960 | child_data->parent = ls, | ||
960 | child_data->filter.cb = pd->filter.cb, | 961 | // NOTE: We are assuming here that the parent model will outlive all its children | ||
961 | child_data->filter.data = pd->filter.data); | 962 | child_data->filter.cb = pd->filter.cb, | ||
963 | child_data->filter.data = pd->filter.data); | ||||
962 | eina_value_array_append(&array, info->object); | 964 | eina_value_array_append(&array, info->object); | ||
963 | 965 | | |||
966 | efl_wref_add(info->object, &info->object); | ||||
967 | efl_unref(info->object); | ||||
968 | | ||||
964 | count--; | 969 | count--; | ||
965 | ls = eina_list_next(ls); | 970 | ls = eina_list_next(ls); | ||
966 | } | 971 | } | ||
967 | 972 | | |||
968 | return eina_future_resolved(scheduler, array); | 973 | return eina_future_resolved(scheduler, array); | ||
969 | } | 974 | } | ||
970 | 975 | | |||
971 | 976 | | |||
Show All 40 Lines | 1016 | { | |||
1012 | return priv->path; | 1017 | return priv->path; | ||
1013 | } | 1018 | } | ||
1014 | 1019 | | |||
1015 | static void | 1020 | static void | ||
1016 | _efl_io_model_efl_object_destructor(Eo *obj , Efl_Io_Model_Data *priv) | 1021 | _efl_io_model_efl_object_destructor(Eo *obj , Efl_Io_Model_Data *priv) | ||
1017 | { | 1022 | { | ||
1018 | Efl_Io_Model_Info *info; | 1023 | Efl_Io_Model_Info *info; | ||
1019 | 1024 | | |||
1025 | | ||||
1026 | free(priv->st); | ||||
1027 | priv->st = NULL; | ||||
1028 | | ||||
1020 | _efl_io_model_info_free(priv->info, EINA_TRUE); | 1029 | _efl_io_model_info_free(priv->info, EINA_TRUE); | ||
1021 | priv->info = NULL; | 1030 | priv->info = NULL; | ||
1022 | 1031 | | |||
1023 | EINA_LIST_FREE(priv->files, info) | 1032 | EINA_LIST_FREE(priv->files, info) | ||
1024 | _efl_io_model_info_free(info, EINA_FALSE); | 1033 | _efl_io_model_info_free(info, EINA_FALSE); | ||
1025 | 1034 | | |||
1026 | eina_stringshare_del(priv->path); | 1035 | eina_stringshare_replace(&priv->path, NULL); | ||
1027 | 1036 | | |||
1028 | efl_destructor(efl_super(obj, MY_CLASS)); | 1037 | efl_destructor(efl_super(obj, MY_CLASS)); | ||
1029 | } | 1038 | } | ||
1030 | 1039 | | |||
1031 | static void | 1040 | static void | ||
1032 | _efl_io_model_efl_object_invalidate(Eo *obj , Efl_Io_Model_Data *priv) | 1041 | _efl_io_model_efl_object_invalidate(Eo *obj , Efl_Io_Model_Data *priv) | ||
1033 | { | 1042 | { | ||
1043 | // This has to be done first, to make sure that the automatic | ||||
1044 | // del is not done anymore. Or it would lead to too much | ||||
1045 | // unref when stopping async thread (During invalidate, we | ||||
1046 | // are already in the process of doing an implicit del). | ||||
1047 | efl_invalidate(efl_super(obj, EFL_IO_MODEL_CLASS)); | ||||
1048 | | ||||
1034 | _efl_io_model_efl_model_monitor_del(priv); | 1049 | _efl_io_model_efl_model_monitor_del(priv); | ||
1035 | 1050 | | |||
1036 | // Unlink the object from the parent | 1051 | // Unlink the object from the parent | ||
1037 | if (priv->info) priv->info->object = NULL; | 1052 | if (priv->info) | ||
1053 | { | ||||
1054 | efl_wref_del(priv->info->object, &priv->info->object); | ||||
1055 | priv->info->object = NULL; | ||||
1056 | } | ||||
1038 | if (priv->request.del) | 1057 | if (priv->request.del) | ||
1039 | { | 1058 | { | ||
1040 | if (!ecore_thread_wait(priv->request.del->thread, 0.1)) | 1059 | if (!ecore_thread_wait(priv->request.del->thread, 0.1)) | ||
1041 | { | 1060 | { | ||
1042 | ecore_thread_cancel(priv->request.del->thread); | 1061 | ecore_thread_cancel(priv->request.del->thread); | ||
1043 | ecore_thread_wait(priv->request.del->thread, 0.1); | 1062 | ecore_thread_wait(priv->request.del->thread, 0.1); | ||
1044 | } | 1063 | } | ||
1045 | } | 1064 | } | ||
1046 | if (priv->request.move) | 1065 | if (priv->request.move) | ||
1047 | { | 1066 | { | ||
1048 | if (!ecore_thread_wait(priv->request.move->thread, 0.1)) | 1067 | if (!ecore_thread_wait(priv->request.move->thread, 0.1)) | ||
1049 | { | 1068 | { | ||
1050 | ecore_thread_cancel(priv->request.move->thread); | 1069 | ecore_thread_cancel(priv->request.move->thread); | ||
1051 | ecore_thread_wait(priv->request.move->thread, 0.1); | 1070 | ecore_thread_wait(priv->request.move->thread, 0.1); | ||
1052 | } | 1071 | } | ||
1053 | } | 1072 | } | ||
1054 | if (priv->request.stat) | 1073 | if (priv->request.stat) | ||
1055 | { | 1074 | { | ||
1056 | if (!ecore_thread_wait(priv->request.stat->thread, 0.1)) | 1075 | if (!ecore_thread_wait(priv->request.stat->thread, 0.1)) | ||
1057 | { | 1076 | { | ||
1058 | ecore_thread_cancel(priv->request.stat->thread); | 1077 | ecore_thread_cancel(priv->request.stat->thread); | ||
1059 | ecore_thread_wait(priv->request.stat->thread, 0.1); | 1078 | ecore_thread_wait(priv->request.stat->thread, 0.1); | ||
1060 | } | 1079 | } | ||
1061 | } | 1080 | } | ||
1062 | | ||||
1063 | efl_invalidate(efl_super(obj, EFL_IO_MODEL_CLASS)); | | |||
1064 | } | 1081 | } | ||
1065 | 1082 | | |||
1066 | #include "efl_io_model.eo.c" | 1083 | #include "efl_io_model.eo.c" |
?