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 56void _dispatch_semaphore_dispose(dispatch_object_t dou); 57size_t _dispatch_semaphore_debug(dispatch_object_t dou, char *buf, 58 size_t bufsiz); 59 60typedef uintptr_t _dispatch_thread_semaphore_t; 61 62_dispatch_thread_semaphore_t _dispatch_thread_semaphore_create(void); 63void _dispatch_thread_semaphore_dispose(_dispatch_thread_semaphore_t); 64void _dispatch_thread_semaphore_wait(_dispatch_thread_semaphore_t); 65void _dispatch_thread_semaphore_signal(_dispatch_thread_semaphore_t); 66 67DISPATCH_ALWAYS_INLINE 68static inline _dispatch_thread_semaphore_t 69_dispatch_get_thread_semaphore(void) 70{ 71 _dispatch_thread_semaphore_t sema = (_dispatch_thread_semaphore_t) 72 _dispatch_thread_getspecific(dispatch_sema4_key); 73 if (slowpath(!sema)) { 74 return _dispatch_thread_semaphore_create(); 75 } 76 _dispatch_thread_setspecific(dispatch_sema4_key, NULL); 77 return sema; 78} 79 80DISPATCH_ALWAYS_INLINE 81static inline void 82_dispatch_put_thread_semaphore(_dispatch_thread_semaphore_t sema) 83{ 84 _dispatch_thread_semaphore_t old_sema = (_dispatch_thread_semaphore_t) 85 _dispatch_thread_getspecific(dispatch_sema4_key); 86 _dispatch_thread_setspecific(dispatch_sema4_key, (void*)sema); 87 if (slowpath(old_sema)) { 88 return _dispatch_thread_semaphore_dispose(old_sema); 89 } 90} 91 92#endif 93