diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_idler.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore/ecore_idler.c b/libraries/ecore/src/lib/ecore/ecore_idler.c new file mode 100644 index 0000000..6c0cab8 --- /dev/null +++ b/libraries/ecore/src/lib/ecore/ecore_idler.c | |||
@@ -0,0 +1,158 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | |||
7 | #include "Ecore.h" | ||
8 | #include "ecore_private.h" | ||
9 | |||
10 | struct _Ecore_Idler | ||
11 | { | ||
12 | EINA_INLIST; | ||
13 | ECORE_MAGIC; | ||
14 | Ecore_Task_Cb func; | ||
15 | void *data; | ||
16 | int references; | ||
17 | Eina_Bool delete_me : 1; | ||
18 | }; | ||
19 | |||
20 | static Ecore_Idler *idlers = NULL; | ||
21 | static Ecore_Idler *idler_current = NULL; | ||
22 | static int idlers_delete_me = 0; | ||
23 | |||
24 | static void * | ||
25 | _ecore_idler_del(Ecore_Idler *idler); | ||
26 | |||
27 | EAPI Ecore_Idler * | ||
28 | ecore_idler_add(Ecore_Task_Cb func, | ||
29 | const void *data) | ||
30 | { | ||
31 | Ecore_Idler *ie = NULL; | ||
32 | |||
33 | _ecore_lock(); | ||
34 | if (!func) goto unlock; | ||
35 | ie = calloc(1, sizeof(Ecore_Idler)); | ||
36 | if (!ie) goto unlock; | ||
37 | ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER); | ||
38 | ie->func = func; | ||
39 | ie->data = (void *)data; | ||
40 | idlers = (Ecore_Idler *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); | ||
41 | unlock: | ||
42 | _ecore_unlock(); | ||
43 | return ie; | ||
44 | } | ||
45 | |||
46 | EAPI void * | ||
47 | ecore_idler_del(Ecore_Idler *idler) | ||
48 | { | ||
49 | void *data = NULL; | ||
50 | |||
51 | if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER)) | ||
52 | { | ||
53 | ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER, | ||
54 | "ecore_idler_del"); | ||
55 | return NULL; | ||
56 | } | ||
57 | |||
58 | _ecore_lock(); | ||
59 | data = _ecore_idler_del(idler); | ||
60 | _ecore_unlock(); | ||
61 | return data; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * @} | ||
66 | */ | ||
67 | |||
68 | /** | ||
69 | * @} | ||
70 | */ | ||
71 | |||
72 | static void * | ||
73 | _ecore_idler_del(Ecore_Idler *idler) | ||
74 | { | ||
75 | EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL); | ||
76 | idler->delete_me = 1; | ||
77 | idlers_delete_me = 1; | ||
78 | return idler->data; | ||
79 | } | ||
80 | |||
81 | void | ||
82 | _ecore_idler_shutdown(void) | ||
83 | { | ||
84 | Ecore_Idler *ie; | ||
85 | while ((ie = idlers)) | ||
86 | { | ||
87 | idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers)); | ||
88 | ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); | ||
89 | free(ie); | ||
90 | } | ||
91 | idlers_delete_me = 0; | ||
92 | idler_current = NULL; | ||
93 | } | ||
94 | |||
95 | int | ||
96 | _ecore_idler_all_call(void) | ||
97 | { | ||
98 | if (!idler_current) | ||
99 | { | ||
100 | /* regular main loop, start from head */ | ||
101 | idler_current = idlers; | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | /* recursive main loop, continue from where we were */ | ||
106 | idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next; | ||
107 | } | ||
108 | |||
109 | while (idler_current) | ||
110 | { | ||
111 | Ecore_Idler *ie = (Ecore_Idler *)idler_current; | ||
112 | if (!ie->delete_me) | ||
113 | { | ||
114 | ie->references++; | ||
115 | if (!_ecore_call_task_cb(ie->func, ie->data)) | ||
116 | { | ||
117 | if (!ie->delete_me) _ecore_idler_del(ie); | ||
118 | } | ||
119 | ie->references--; | ||
120 | } | ||
121 | if (idler_current) /* may have changed in recursive main loops */ | ||
122 | idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next; | ||
123 | } | ||
124 | if (idlers_delete_me) | ||
125 | { | ||
126 | Ecore_Idler *l; | ||
127 | int deleted_idlers_in_use = 0; | ||
128 | for (l = idlers; l; ) | ||
129 | { | ||
130 | Ecore_Idler *ie = l; | ||
131 | l = (Ecore_Idler *)EINA_INLIST_GET(l)->next; | ||
132 | if (ie->delete_me) | ||
133 | { | ||
134 | if (ie->references) | ||
135 | { | ||
136 | deleted_idlers_in_use++; | ||
137 | continue; | ||
138 | } | ||
139 | |||
140 | idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); | ||
141 | ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); | ||
142 | free(ie); | ||
143 | } | ||
144 | } | ||
145 | if (!deleted_idlers_in_use) | ||
146 | idlers_delete_me = 0; | ||
147 | } | ||
148 | if (idlers) return 1; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | int | ||
153 | _ecore_idler_exist(void) | ||
154 | { | ||
155 | if (idlers) return 1; | ||
156 | return 0; | ||
157 | } | ||
158 | |||