summaryrefslogtreecommitdiff
path: root/src/lib/eio/eio_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eio/eio_main.c')
-rw-r--r--src/lib/eio/eio_main.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/lib/eio/eio_main.c b/src/lib/eio/eio_main.c
new file mode 100644
index 0000000..e65f75b
--- /dev/null
+++ b/src/lib/eio/eio_main.c
@@ -0,0 +1,300 @@
1/* EIO - EFL data type library
2 * Copyright (C) 2010 Enlightenment Developers:
3 * Cedric Bail <cedric.bail@free.fr>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library;
17 * if not, see <http://www.gnu.org/licenses/>.
18 */
19#include "eio_private.h"
20#include "Eio.h"
21
22/*============================================================================*
23 * Local *
24 *============================================================================*/
25
26static Eio_Version _version = { VMAJ, VMIN, VMIC, VREV };
27EAPI Eio_Version *eio_version = &_version;
28
29/**
30 * @cond LOCAL
31 */
32
33#ifdef EFL_HAVE_POSIX_THREADS
34# define EIO_MUTEX_TYPE pthread_mutex_t
35# define EIO_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
36# define EIO_MUTEX_INIT(Pool)
37# define EIO_MUTEX_LOCK(Pool) pthread_mutex_lock(&Pool->lock)
38# define EIO_MUTEX_UNLOCK(Pool) pthread_mutex_unlock(&Pool->lock)
39# define EIO_MUTEX_DESTROY(Pool)
40#endif
41
42#ifdef EFL_HAVE_WIN32_THREADS
43# define EIO_MUTEX_TYPE HANDLE
44# define EIO_MUTEX_INITIALIZER NULL
45# define EIO_MUTEX_INIT(Pool) Pool.lock = CreateMutex(NULL, FALSE, NULL)
46# define EIO_MUTEX_LOCK(Pool) WaitForSingleObject(Pool->lock, INFINITE)
47# define EIO_MUTEX_UNLOCK(Pool) ReleaseMutex(Pool->lock)
48# define EIO_MUTEX_DESTROY(Pool) CloseHandle(Pool.lock)
49#endif
50
51/* Progress pool */
52typedef struct _Eio_Alloc_Pool Eio_Alloc_Pool;
53
54struct _Eio_Alloc_Pool
55{
56 int count;
57 Eina_Trash *trash;
58
59 EIO_MUTEX_TYPE lock;
60};
61
62static int _eio_init_count = 0;
63int _eio_log_dom_global = -1;
64
65static Eio_Alloc_Pool progress_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
66static Eio_Alloc_Pool direct_info_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
67static Eio_Alloc_Pool char_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
68static Eio_Alloc_Pool associate_pool = { 0, NULL, EIO_MUTEX_INITIALIZER };
69
70static void *
71_eio_pool_malloc(Eio_Alloc_Pool *pool, size_t sz)
72{
73 void *result = NULL;
74
75 if (pool->count)
76 {
77 EIO_MUTEX_LOCK(pool);
78 result = eina_trash_pop(&pool->trash);
79 if (result) pool->count--;
80 EIO_MUTEX_UNLOCK(pool);
81 }
82
83 if (!result) result = malloc(sz);
84 return result;
85}
86
87static void
88_eio_pool_free(Eio_Alloc_Pool *pool, void *data)
89{
90 if (pool->count >= EIO_PROGRESS_LIMIT)
91 {
92 free(data);
93 }
94 else
95 {
96 EIO_MUTEX_LOCK(pool);
97 eina_trash_push(&pool->trash, data);
98 pool->count++;
99 EIO_MUTEX_UNLOCK(pool);
100 }
101}
102
103/**
104 * @endcond
105 */
106
107/*============================================================================*
108 * Global *
109 *============================================================================*/
110
111/**
112 * @cond LOCAL
113 */
114
115Eio_Progress *
116eio_progress_malloc(void)
117{
118 return _eio_pool_malloc(&progress_pool, sizeof (Eio_Progress));
119}
120
121void
122eio_progress_free(Eio_Progress *data)
123{
124 eina_stringshare_del(data->source);
125 eina_stringshare_del(data->dest);
126
127 _eio_pool_free(&progress_pool, data);
128}
129
130void
131eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op, long long current, long long max)
132{
133 Eio_Progress *progress;
134
135 if (op->progress_cb == NULL)
136 return ;
137
138 progress = eio_progress_malloc();
139 if (!progress) return ;
140
141 progress->op = op->op;
142 progress->current = current;
143 progress->max = max;
144 progress->percent = (float) current * 100.0 / (float) max;
145 progress->source = eina_stringshare_ref(op->source);
146 progress->dest = eina_stringshare_ref(op->dest);
147
148 ecore_thread_feedback(thread, progress);
149}
150
151Eio_File_Direct_Info *
152eio_direct_info_malloc(void)
153{
154 return _eio_pool_malloc(&direct_info_pool, sizeof (Eio_File_Direct_Info));
155}
156
157void
158eio_direct_info_free(Eio_File_Direct_Info *data)
159{
160 _eio_pool_free(&direct_info_pool, data);
161}
162
163Eio_File_Char *
164eio_char_malloc(void)
165{
166 return _eio_pool_malloc(&char_pool, sizeof (Eio_File_Char));
167}
168
169void
170eio_char_free(Eio_File_Char *data)
171{
172 _eio_pool_free(&char_pool, data);
173}
174
175Eio_File_Associate *
176eio_associate_malloc(const void *data, Eina_Free_Cb free_cb)
177{
178 Eio_File_Associate *tmp;
179
180 tmp = _eio_pool_malloc(&associate_pool, sizeof (Eio_File_Associate));
181 if (!tmp) return tmp;
182
183 tmp->data = (void*) data;
184 tmp->free_cb = free_cb;
185
186 return tmp;
187}
188
189void
190eio_associate_free(void *data)
191{
192 Eio_File_Associate *tmp;
193
194 if (!data) return ;
195
196 tmp = data;
197 if (tmp->free_cb)
198 tmp->free_cb(tmp->data);
199 _eio_pool_free(&associate_pool, tmp);
200}
201
202
203/**
204 * @endcond
205 */
206
207
208/*============================================================================*
209 * API *
210 *============================================================================*/
211
212EAPI int
213eio_init(void)
214{
215 if (++_eio_init_count != 1)
216 return _eio_init_count;
217
218 if (!eina_init())
219 {
220 fprintf(stderr, "Eio can not initialize Eina\n");
221 return --_eio_init_count;
222 }
223
224 _eio_log_dom_global = eina_log_domain_register("eio", EIO_DEFAULT_LOG_COLOR);
225 if (_eio_log_dom_global < 0)
226 {
227 EINA_LOG_ERR("Eio can not create a general log domain.");
228 goto shutdown_eina;
229 }
230
231 if (!ecore_init())
232 {
233 ERR("Can not initialize Eina\n");
234 goto unregister_log_domain;
235 }
236
237 EIO_MUTEX_INIT(progress_pool);
238 EIO_MUTEX_INIT(direct_info_pool);
239 EIO_MUTEX_INIT(char_pool);
240 EIO_MUTEX_INIT(associate_pool);
241
242 eio_monitor_init();
243
244 return _eio_init_count;
245
246unregister_log_domain:
247 eina_log_domain_unregister(_eio_log_dom_global);
248 _eio_log_dom_global = -1;
249shutdown_eina:
250 eina_shutdown();
251 return --_eio_init_count;
252}
253
254EAPI int
255eio_shutdown(void)
256{
257 Eio_File_Direct_Info *info;
258 Eio_File_Char *cin;
259 Eio_Progress *pg;
260 Eio_File_Associate *asso;
261
262 if (_eio_init_count <= 0)
263 {
264 ERR("Init count not greater than 0 in shutdown.");
265 return 0;
266 }
267 if (--_eio_init_count != 0)
268 return _eio_init_count;
269
270 eio_monitor_shutdown();
271
272 EIO_MUTEX_DESTROY(direct_info_pool);
273 EIO_MUTEX_DESTROY(progress_pool);
274 EIO_MUTEX_DESTROY(char_pool);
275 EIO_MUTEX_DESTROY(associate_pool);
276
277 /* Cleanup pool */
278 EINA_TRASH_CLEAN(&progress_pool.trash, pg)
279 free(pg);
280 progress_pool.count = 0;
281
282 EINA_TRASH_CLEAN(&direct_info_pool.trash, info)
283 free(info);
284 direct_info_pool.count = 0;
285
286 EINA_TRASH_CLEAN(&char_pool.trash, cin)
287 free(cin);
288 char_pool.count = 0;
289
290 EINA_TRASH_CLEAN(&associate_pool.trash, asso)
291 free(asso);
292 associate_pool.count = 0;
293
294 ecore_shutdown();
295 eina_log_domain_unregister(_eio_log_dom_global);
296 _eio_log_dom_global = -1;
297 eina_shutdown();
298
299 return _eio_init_count;
300}