Tizen 2.1 base
[platform/upstream/gcd.git] / dispatch-1.0 / src / legacy.c
1 /*
2  * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
3  *
4  * @APPLE_APACHE_LICENSE_HEADER_START@
5  * 
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  * 
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  * 
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  * 
18  * @APPLE_APACHE_LICENSE_HEADER_END@
19  */
20
21 #include "internal.h"
22
23 #ifndef DISPATCH_NO_LEGACY
24 #include "legacy.h"
25
26 /*
27  * LEGACY: This header file describles LEGACY interfaces to libdispatch from an
28  * earlier revision of the API. These interfaces WILL be removed in the future.
29  */
30
31 #ifdef __BLOCKS__
32 DISPATCH_PUBLIC_API DISPATCH_NONNULL1 DISPATCH_NONNULL2
33 dispatch_item_t
34 LEGACY_dispatch_call(dispatch_queue_t, dispatch_legacy_block_t work, dispatch_legacy_block_t completion)
35 __asm__("_dispatch_call2");
36 #endif
37
38 DISPATCH_PUBLIC_API DISPATCH_PURE DISPATCH_WARN_RESULT
39 dispatch_queue_t
40 LEGACY_dispatch_queue_get_current(void)
41 __asm__("_dispatch_queue_get_current");
42
43 /////////////////////////////////////////////////////////////////////////////
44
45 dispatch_queue_t
46 LEGACY_dispatch_queue_get_current(void)
47 {
48         return _dispatch_queue_get_current();
49 }
50
51 #ifdef __BLOCKS__
52 dispatch_item_t
53 LEGACY_dispatch_call(dispatch_queue_t dq,
54         dispatch_legacy_block_t dispatch_block,
55         dispatch_legacy_block_t callback_block)
56 {
57         dispatch_queue_t lq = _dispatch_queue_get_current() ?: dispatch_get_main_queue();
58         dispatch_item_t di;
59
60         di = dispatch_block ? calloc(1, ROUND_UP_TO_CACHELINE_SIZE(sizeof(*di))) : NULL;
61
62         if (!di) {
63                 return di;
64         }
65
66         if (callback_block) {
67                 dispatch_retain(lq);
68         }
69
70         dispatch_async(dq, ^{
71                 dispatch_block(di);
72
73                 if (callback_block) {
74                         dispatch_async(lq, ^{
75                                 callback_block(di);
76                                 free(di);
77                                 dispatch_release(lq);
78                         });
79                 } else {
80                         free(di);
81                 }
82         });
83
84         return di;
85 }
86 #endif /* __BLOCKS__ */
87
88 sigset_t
89 dispatch_event_get_signals(dispatch_event_t de)
90 {
91         sigset_t ret;
92         sigemptyset(&ret);
93         sigaddset(&ret, (int)dispatch_event_get_signal(de));
94         return ret;
95 }
96
97 void dispatch_cancel(dispatch_source_t ds) { dispatch_source_cancel(ds); }
98 long dispatch_testcancel(dispatch_source_t ds) { return dispatch_source_testcancel(ds); }
99
100 void dispatch_queue_resume(dispatch_queue_t dq) { dispatch_resume(dq); }
101 void dispatch_queue_retain(dispatch_queue_t dq) { dispatch_retain(dq); }
102 void dispatch_queue_release(dispatch_queue_t dq) { dispatch_release(dq); }
103
104 void dispatch_source_suspend(dispatch_source_t ds) { dispatch_suspend(ds); }
105 void dispatch_source_resume(dispatch_source_t ds) { dispatch_resume(ds); }
106 void dispatch_source_release(dispatch_source_t ds) { dispatch_release(ds); }
107
108 void dispatch_source_attr_release(dispatch_source_attr_t attr) { dispatch_release(attr); }
109 void dispatch_queue_attr_release(dispatch_queue_attr_t attr) { dispatch_release(attr); }
110
111 void *dispatch_queue_get_context(dispatch_queue_t dq) { return dispatch_get_context(dq); }
112 void  dispatch_queue_set_context(dispatch_queue_t dq, void *context) { dispatch_set_context(dq, context); }
113
114 void *dispatch_source_get_context(dispatch_source_t ds) { return dispatch_get_context(ds); }
115 void  dispatch_source_set_context(dispatch_source_t ds, void *context) { dispatch_set_context(ds, context); }
116
117 void dispatch_source_custom_trigger(dispatch_source_t ds) { dispatch_source_merge_data(ds, 1); }
118
119 void
120 dispatch_source_trigger(dispatch_source_t ds, unsigned long val)
121 {
122         dispatch_source_merge_data(ds, val);
123 }
124
125 int dispatch_source_get_descriptor(dispatch_source_t ds) { return (int)dispatch_source_get_handle(ds); }
126
127 pid_t dispatch_source_get_pid(dispatch_source_t ds) { return (pid_t)dispatch_source_get_handle(ds); }
128
129 mach_port_t dispatch_source_get_machport(dispatch_source_t ds) { return (mach_port_t)dispatch_source_get_handle(ds); }
130
131 uint64_t dispatch_source_get_flags(dispatch_source_t ds) { return dispatch_source_get_mask(ds); }
132
133 dispatch_source_t dispatch_event_get_source(dispatch_event_t event) { return event; }
134
135 long dispatch_event_get_error(dispatch_event_t event, long* error) { return dispatch_source_get_error(event, error); }
136
137 uint64_t dispatch_event_get_flags(dispatch_event_t event)  { return dispatch_source_get_data(event); }
138
139 size_t dispatch_event_get_bytes_available(dispatch_event_t event) { return (size_t)dispatch_source_get_data(event); }
140
141 unsigned long dispatch_event_get_count(dispatch_event_t event) { return (unsigned long)dispatch_source_get_data(event); }
142
143 long dispatch_event_get_signal(dispatch_event_t event) { return (long)dispatch_source_get_handle(event); }
144
145 dispatch_source_t
146 dispatch_source_custom_create(
147                                                           unsigned long behavior,
148                                                           dispatch_source_attr_t attr,
149                                                           dispatch_queue_t queue,
150                                                           dispatch_event_handler_t handler) {
151         return dispatch_source_data_create(behavior, attr, queue, handler);
152 }
153
154 dispatch_source_t
155 dispatch_source_custom_create_f(
156                                                                 unsigned long behavior,
157                                                                 dispatch_source_attr_t attr,
158                                                                 dispatch_queue_t queue,
159                                                                 void *h_context,
160                                                                 dispatch_event_handler_function_t handler) {
161         return dispatch_source_data_create_f(behavior, attr, queue, h_context, handler);
162 }
163
164 #define _dispatch_source_call_block ((void *)-1)
165
166
167
168 #ifdef __BLOCKS__
169 dispatch_source_t
170 dispatch_source_timer_create(uint64_t flags,
171         uint64_t nanoseconds,
172         uint64_t leeway,
173         dispatch_source_attr_t attr,
174         dispatch_queue_t q,
175         dispatch_source_handler_t callback)
176 {
177         return dispatch_source_timer_create_f(flags, nanoseconds, leeway,
178                 attr, q, callback, _dispatch_source_call_block);
179 }
180 #endif
181
182 dispatch_source_t
183 dispatch_source_timer_create_f(uint64_t timer_flags,
184         uint64_t nanoseconds,
185         uint64_t leeway,
186         dispatch_source_attr_t attr,
187         dispatch_queue_t q,
188         void *context, 
189         dispatch_source_handler_function_t callback)
190 {
191         dispatch_source_t ds;
192         dispatch_time_t start;
193
194         // 6866347 - make sure nanoseconds won't overflow
195         if ((int64_t)nanoseconds < 0) {
196                 nanoseconds = INT64_MAX;
197         }
198
199         if (timer_flags & DISPATCH_TIMER_ONESHOT) {
200                 timer_flags |= DISPATCH_TIMER_WALL_CLOCK;
201         }
202         if (timer_flags == (DISPATCH_TIMER_ABSOLUTE|DISPATCH_TIMER_WALL_CLOCK)) {
203                 static const struct timespec t0;
204                 start = dispatch_walltime(&t0, nanoseconds);
205         } else if (timer_flags & DISPATCH_TIMER_WALL_CLOCK) {
206                 start = dispatch_walltime(DISPATCH_TIME_NOW, nanoseconds);
207         } else {
208                 start = dispatch_time(DISPATCH_TIME_NOW, nanoseconds);
209         }
210         if (timer_flags & DISPATCH_TIMER_ONESHOT) {
211                 // 6866347 - make sure nanoseconds won't overflow
212                 nanoseconds = INT64_MAX; // non-repeating (~292 years)
213         }
214
215         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, (unsigned long)timer_flags, q);
216         if (!ds) {
217                 return NULL;
218         }
219         ds = _dispatch_source_create2(ds, attr, context, callback);
220         if (!ds) {
221                 return NULL;
222         }
223         dispatch_source_set_timer(ds, start, nanoseconds, leeway);
224
225         return ds;
226 }
227
228 #ifdef __BLOCKS__
229 dispatch_source_t
230 dispatch_source_read_create(int descriptor,
231         dispatch_source_attr_t attr,
232         dispatch_queue_t q,
233         dispatch_source_handler_t callback)
234 {
235         return dispatch_source_read_create_f(descriptor,
236                 attr, q, callback, _dispatch_source_call_block);
237 }
238 #endif
239
240 dispatch_source_t
241 dispatch_source_read_create_f(int fd,
242         dispatch_source_attr_t attr,
243         dispatch_queue_t q,
244         void *context,
245         dispatch_source_handler_function_t callback)
246 {
247         dispatch_source_t ds;
248         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, q);
249         return _dispatch_source_create2(ds, attr, context, callback);
250 }
251
252 #ifdef __BLOCKS__
253 dispatch_source_t
254 dispatch_source_write_create(int descriptor,
255         dispatch_source_attr_t attr,
256         dispatch_queue_t q,
257         dispatch_source_handler_t callback)
258 {
259         return dispatch_source_write_create_f(descriptor,
260                 attr, q, callback, _dispatch_source_call_block);
261 }
262 #endif
263
264 dispatch_source_t
265 dispatch_source_write_create_f(int fd,
266         dispatch_source_attr_t attr,
267         dispatch_queue_t q,
268         void *context,
269         dispatch_source_handler_function_t callback)
270 {
271         dispatch_source_t ds;
272         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, q);
273         return _dispatch_source_create2(ds, attr, context, callback);
274 }
275
276 #ifdef __BLOCKS__
277 dispatch_source_t
278 dispatch_source_vnode_create(int descriptor,
279         uint64_t flags,
280         dispatch_source_attr_t attr,
281         dispatch_queue_t q,
282         dispatch_source_handler_t callback)
283 {
284         return dispatch_source_vnode_create_f(descriptor,
285                 flags, attr, q, callback, _dispatch_source_call_block);
286 }
287 #endif
288
289 dispatch_source_t
290 dispatch_source_vnode_create_f(int fd,
291         uint64_t event_mask,
292         dispatch_source_attr_t attr,
293         dispatch_queue_t q,
294         void *context,
295         dispatch_source_handler_function_t callback)
296 {
297         dispatch_source_t ds;
298         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, (unsigned long)event_mask, q);
299         return _dispatch_source_create2(ds, attr, context, callback);
300 }
301
302 #ifdef __BLOCKS__
303 dispatch_source_t
304 dispatch_source_signal_create(unsigned long sig,
305         dispatch_source_attr_t attr,
306         dispatch_queue_t q,
307         dispatch_source_handler_t callback)
308 {
309         return dispatch_source_signal_create_f(sig,
310                 attr, q, callback, _dispatch_source_call_block);
311 }
312 #endif
313
314 dispatch_source_t
315 dispatch_source_signal_create_f(unsigned long signo,
316         dispatch_source_attr_t attr,
317         dispatch_queue_t q,
318         void *context,
319         dispatch_source_handler_function_t callback)
320 {
321         dispatch_source_t ds;
322         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, signo, 0, q);
323         return _dispatch_source_create2(ds, attr, context, callback);
324 }
325
326 #ifdef __BLOCKS__
327 dispatch_source_t
328 dispatch_source_proc_create(pid_t pid,
329         uint64_t flags,
330         dispatch_source_attr_t attr,
331         dispatch_queue_t q,
332         dispatch_source_handler_t callback)
333 {
334         return dispatch_source_proc_create_f(pid,
335                 flags, attr, q, callback, _dispatch_source_call_block);
336 }
337 #endif
338
339 dispatch_source_t
340 dispatch_source_proc_create_f(pid_t pid,
341         uint64_t event_mask,
342         dispatch_source_attr_t attr,
343         dispatch_queue_t q,
344         void *context,
345         dispatch_source_handler_function_t callback)
346 {
347         dispatch_source_t ds;
348         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, (unsigned long)event_mask, q);
349         return _dispatch_source_create2(ds, attr, context, callback);
350 }
351
352 #ifdef __BLOCKS__
353 dispatch_source_t
354 dispatch_source_vfs_create(uint64_t flags,
355         dispatch_source_attr_t attr,
356         dispatch_queue_t q,
357         dispatch_source_handler_t callback)
358 {
359         return dispatch_source_vfs_create_f(flags,
360                 attr, q, callback, _dispatch_source_call_block);
361 }
362 #endif
363
364 dispatch_source_t
365 dispatch_source_vfs_create_f(uint64_t event_mask,
366         dispatch_source_attr_t attr,
367         dispatch_queue_t q,
368         void *context,
369         dispatch_source_handler_function_t callback)
370 {
371         dispatch_source_t ds;
372         ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_VFS, 0, (unsigned long)event_mask, q);
373         return _dispatch_source_create2(ds, attr, context, callback);
374 }
375
376 #ifdef __BLOCKS__
377 dispatch_source_t
378 dispatch_source_data_create(unsigned long behavior,
379         dispatch_source_attr_t attr,
380         dispatch_queue_t q,
381         dispatch_source_handler_t callback)
382 {
383         return dispatch_source_data_create_f(behavior,
384                 attr, q, callback, _dispatch_source_call_block);
385 }
386 #endif
387
388 #ifdef __BLOCKS__
389 dispatch_source_t
390 dispatch_source_machport_create(mach_port_t mport,
391         uint64_t flags,
392         dispatch_source_attr_t attr,
393         dispatch_queue_t dq,
394         dispatch_source_handler_t callback)
395 {
396         return dispatch_source_machport_create_f(mport, flags,
397                 attr, dq, callback, _dispatch_source_call_block);
398 }
399 #endif
400
401 dispatch_source_t
402 dispatch_source_data_create_f(unsigned long behavior,
403         dispatch_source_attr_t attr,
404         dispatch_queue_t q,
405         void *context,
406         dispatch_source_handler_function_t callback)
407 {
408         dispatch_source_t ds;
409         dispatch_source_type_t type;
410         switch (behavior) {
411                 case DISPATCH_SOURCE_CUSTOM_ADD:
412                         type = DISPATCH_SOURCE_TYPE_DATA_ADD;
413                         break;
414                 case DISPATCH_SOURCE_CUSTOM_OR:
415                         type = DISPATCH_SOURCE_TYPE_DATA_OR;
416                         break;
417                 default:
418                         return NULL;
419         }
420         ds = dispatch_source_create(type, 0, 0, q);
421         return _dispatch_source_create2(ds, attr, context, callback);
422 }
423
424 dispatch_source_t
425 dispatch_source_machport_create_f(mach_port_t mport,
426         uint64_t flags,
427         dispatch_source_attr_t attr,
428         dispatch_queue_t dq,
429         void *ctxt,
430         dispatch_source_handler_function_t func)
431 {
432         dispatch_source_t ds;
433         dispatch_source_type_t type;
434         unsigned long newflags = 0;
435
436         if (flags & ~(DISPATCH_MACHPORT_DEAD|DISPATCH_MACHPORT_RECV)) {
437                 return NULL;
438         }
439         // XXX DELETED
440         if (flags & DISPATCH_MACHPORT_DEAD) {
441                 type = DISPATCH_SOURCE_TYPE_MACH_SEND;
442                 newflags |= DISPATCH_MACH_SEND_DEAD;
443         } else {
444                 type = DISPATCH_SOURCE_TYPE_MACH_RECV;
445         }
446
447         ds = dispatch_source_create(type, mport, newflags, dq);
448         return _dispatch_source_create2(ds, attr, ctxt, func);
449 }
450
451 #endif /* DISPATCH_NO_LEGACY */
452