aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore/ecore_idler.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_idler.c158
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
10struct _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
20static Ecore_Idler *idlers = NULL;
21static Ecore_Idler *idler_current = NULL;
22static int idlers_delete_me = 0;
23
24static void *
25_ecore_idler_del(Ecore_Idler *idler);
26
27EAPI Ecore_Idler *
28ecore_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));
41unlock:
42 _ecore_unlock();
43 return ie;
44}
45
46EAPI void *
47ecore_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
72static 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
81void
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
95int
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
152int
153_ecore_idler_exist(void)
154{
155 if (idlers) return 1;
156 return 0;
157}
158