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