1/* 2 * Copyright (c) 2008-2013 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/* 22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch 23 * which are subject to change in future releases of Mac OS X. Any applications 24 * relying on these interfaces WILL break. 25 */ 26 27#ifndef __DISPATCH_SEMAPHORE_INTERNAL__ 28#define __DISPATCH_SEMAPHORE_INTERNAL__ 29 30struct dispatch_queue_s; 31 32DISPATCH_CLASS_DECL(semaphore); 33struct dispatch_semaphore_s { 34 DISPATCH_STRUCT_HEADER(semaphore); 35#if USE_MACH_SEM 36 semaphore_t dsema_port; 37#elif USE_POSIX_SEM 38 sem_t dsema_sem; 39#elif USE_WIN32_SEM 40 HANDLE dsema_handle; 41#else 42#error "No supported semaphore type" 43#endif 44 long dsema_orig; 45 long volatile dsema_value; 46 union { 47 long volatile dsema_sent_ksignals; 48 long volatile dsema_group_waiters; 49 }; 50 struct dispatch_continuation_s *volatile dsema_notify_head; 51 struct dispatch_continuation_s *volatile dsema_notify_tail; 52}; 53 54DISPATCH_CLASS_DECL(group); 55 56#define DISPATCH_GROUP_INITIALIZER(s) \ 57 { \ 58 .do_vtable = (const void*)DISPATCH_VTABLE(group), \ 59 .do_ref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT, \ 60 .do_xref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT, \ 61 .dsema_value = LONG_MAX - (s), \ 62 .dsema_orig = LONG_MAX, \ 63 } 64 65void _dispatch_semaphore_dispose(dispatch_object_t dou); 66size_t _dispatch_semaphore_debug(dispatch_object_t dou, char *buf, 67 size_t bufsiz); 68 69typedef uintptr_t _dispatch_thread_semaphore_t; 70 71_dispatch_thread_semaphore_t _dispatch_thread_semaphore_create(void); 72void _dispatch_thread_semaphore_dispose(_dispatch_thread_semaphore_t); 73void _dispatch_thread_semaphore_wait(_dispatch_thread_semaphore_t); 74void _dispatch_thread_semaphore_signal(_dispatch_thread_semaphore_t); 75 76DISPATCH_ALWAYS_INLINE 77static inline _dispatch_thread_semaphore_t 78_dispatch_get_thread_semaphore(void) 79{ 80 _dispatch_thread_semaphore_t sema = (_dispatch_thread_semaphore_t) 81 _dispatch_thread_getspecific(dispatch_sema4_key); 82 if (slowpath(!sema)) { 83 return _dispatch_thread_semaphore_create(); 84 } 85 _dispatch_thread_setspecific(dispatch_sema4_key, NULL); 86 return sema; 87} 88 89DISPATCH_ALWAYS_INLINE 90static inline void 91_dispatch_put_thread_semaphore(_dispatch_thread_semaphore_t sema) 92{ 93 _dispatch_thread_semaphore_t old_sema = (_dispatch_thread_semaphore_t) 94 _dispatch_thread_getspecific(dispatch_sema4_key); 95 _dispatch_thread_setspecific(dispatch_sema4_key, (void*)sema); 96 if (slowpath(old_sema)) { 97 return _dispatch_thread_semaphore_dispose(old_sema); 98 } 99} 100 101#endif 102