2 * Copyright (c) 2008-2010 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
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.
27 #ifndef __DISPATCH_OBJECT_INTERNAL__
28 #define __DISPATCH_OBJECT_INTERNAL__
30 #if OS_OBJECT_USE_OBJC
31 #define DISPATCH_DECL_INTERNAL_SUBCLASS(name, super) \
32 OS_OBJECT_DECL_SUBCLASS(name, super)
33 #define DISPATCH_DECL_INTERNAL(name) \
34 DISPATCH_DECL_INTERNAL_SUBCLASS(name, dispatch_object)
35 #define DISPATCH_DECL_SUBCLASS_INTERFACE(name, super) \
36 _OS_OBJECT_DECL_SUBCLASS_INTERFACE(name, super)
38 #define DISPATCH_DECL_INTERNAL_SUBCLASS(name, super) DISPATCH_DECL(name)
39 #define DISPATCH_DECL_INTERNAL(name) DISPATCH_DECL(name)
40 #define DISPATCH_DECL_SUBCLASS_INTERFACE(name, super)
41 #endif // OS_OBJECT_USE_OBJC
44 #define DISPATCH_CLASS(name) OS_OBJECT_CLASS(dispatch_##name)
45 // ObjC classes and dispatch vtables are co-located via linker order and alias
46 // files rdar://10640168
47 #define DISPATCH_VTABLE_SUBCLASS_INSTANCE(name, super, ...) \
48 __attribute__((section("__DATA,__objc_data"), used)) \
49 static const struct { \
50 DISPATCH_VTABLE_HEADER(super); \
51 } DISPATCH_CONCAT(_,DISPATCH_CLASS(name##_vtable)) = { \
55 #define DISPATCH_VTABLE_SUBCLASS_INSTANCE(name, super, ...) \
56 const struct dispatch_##super##_vtable_s _dispatch_##name##_vtable = { \
57 ._os_obj_xref_dispose = _dispatch_xref_dispose, \
58 ._os_obj_dispose = _dispatch_dispose, \
63 #define DISPATCH_SUBCLASS_DECL(name, super) \
64 DISPATCH_DECL_SUBCLASS_INTERFACE(dispatch_##name, super) \
65 struct dispatch_##name##_s; \
66 extern const struct dispatch_##name##_vtable_s { \
67 _OS_OBJECT_CLASS_HEADER(); \
68 DISPATCH_VTABLE_HEADER(name); \
69 } _dispatch_##name##_vtable
70 #define DISPATCH_CLASS_DECL(name) DISPATCH_SUBCLASS_DECL(name, dispatch_object)
71 #define DISPATCH_INTERNAL_SUBCLASS_DECL(name, super) \
72 DISPATCH_DECL_INTERNAL_SUBCLASS(dispatch_##name, dispatch_##super); \
73 DISPATCH_DECL_SUBCLASS_INTERFACE(dispatch_##name, dispatch_##super) \
74 extern const struct dispatch_##super##_vtable_s _dispatch_##name##_vtable
75 #define DISPATCH_VTABLE_INSTANCE(name, ...) \
76 DISPATCH_VTABLE_SUBCLASS_INSTANCE(name, name, __VA_ARGS__)
77 #define DISPATCH_VTABLE(name) &_dispatch_##name##_vtable
79 #define DISPATCH_VTABLE_HEADER(x) \
80 unsigned long const do_type; \
81 const char *const do_kind; \
82 size_t (*const do_debug)(struct dispatch_##x##_s *, char *, size_t); \
83 struct dispatch_queue_s *(*const do_invoke)(struct dispatch_##x##_s *); \
84 bool (*const do_probe)(struct dispatch_##x##_s *); \
85 void (*const do_dispose)(struct dispatch_##x##_s *)
87 #define dx_type(x) (x)->do_vtable->do_type
88 #define dx_kind(x) (x)->do_vtable->do_kind
89 #define dx_debug(x, y, z) (x)->do_vtable->do_debug((x), (y), (z))
90 #define dx_dispose(x) (x)->do_vtable->do_dispose(x)
91 #define dx_invoke(x) (x)->do_vtable->do_invoke(x)
92 #define dx_probe(x) (x)->do_vtable->do_probe(x)
94 #define DISPATCH_STRUCT_HEADER(x) \
96 const struct dispatch_##x##_vtable_s *do_vtable, \
99 struct dispatch_##x##_s *volatile do_next; \
100 struct dispatch_queue_s *do_targetq; \
102 void *do_finalizer; \
103 unsigned int do_suspend_cnt;
105 #define DISPATCH_OBJECT_GLOBAL_REFCNT _OS_OBJECT_GLOBAL_REFCNT
106 // "word and bit" must be a power of two to be safely subtracted
107 #define DISPATCH_OBJECT_SUSPEND_LOCK 1u
108 #define DISPATCH_OBJECT_SUSPEND_INTERVAL 2u
109 #define DISPATCH_OBJECT_SUSPENDED(x) \
110 ((x)->do_suspend_cnt >= DISPATCH_OBJECT_SUSPEND_INTERVAL)
112 // the bottom nibble must not be zero, the rest of the bits should be random
113 // we sign extend the 64-bit version so that a better instruction encoding is
114 // generated on Intel
115 #define DISPATCH_OBJECT_LISTLESS ((void *)0xffffffff89abcdef)
117 #define DISPATCH_OBJECT_LISTLESS ((void *)0x89abcdef)
121 _DISPATCH_CONTINUATION_TYPE
= 0x00000, // meta-type for continuations
122 _DISPATCH_QUEUE_TYPE
= 0x10000, // meta-type for queues
123 _DISPATCH_SOURCE_TYPE
= 0x20000, // meta-type for sources
124 _DISPATCH_SEMAPHORE_TYPE
= 0x30000, // meta-type for semaphores
125 _DISPATCH_NODE_TYPE
= 0x40000, // meta-type for data node
126 _DISPATCH_IO_TYPE
= 0x50000, // meta-type for io channels
127 _DISPATCH_OPERATION_TYPE
= 0x60000, // meta-type for io operations
128 _DISPATCH_DISK_TYPE
= 0x70000, // meta-type for io disks
129 _DISPATCH_META_TYPE_MASK
= 0xfff0000, // mask for object meta-types
130 _DISPATCH_ATTR_TYPE
= 0x10000000, // meta-type for attributes
132 DISPATCH_CONTINUATION_TYPE
= _DISPATCH_CONTINUATION_TYPE
,
134 DISPATCH_DATA_TYPE
= _DISPATCH_NODE_TYPE
,
136 DISPATCH_IO_TYPE
= _DISPATCH_IO_TYPE
,
137 DISPATCH_OPERATION_TYPE
= _DISPATCH_OPERATION_TYPE
,
138 DISPATCH_DISK_TYPE
= _DISPATCH_DISK_TYPE
,
140 DISPATCH_QUEUE_ATTR_TYPE
= _DISPATCH_QUEUE_TYPE
|_DISPATCH_ATTR_TYPE
,
142 DISPATCH_QUEUE_TYPE
= 1 | _DISPATCH_QUEUE_TYPE
,
143 DISPATCH_QUEUE_GLOBAL_TYPE
= 2 | _DISPATCH_QUEUE_TYPE
,
144 DISPATCH_QUEUE_MGR_TYPE
= 3 | _DISPATCH_QUEUE_TYPE
,
145 DISPATCH_QUEUE_SPECIFIC_TYPE
= 4 | _DISPATCH_QUEUE_TYPE
,
147 DISPATCH_SEMAPHORE_TYPE
= 1 | _DISPATCH_SEMAPHORE_TYPE
,
148 DISPATCH_GROUP_TYPE
= 2 | _DISPATCH_SEMAPHORE_TYPE
,
150 DISPATCH_SOURCE_KEVENT_TYPE
= 1 | _DISPATCH_SOURCE_TYPE
,
153 DISPATCH_SUBCLASS_DECL(object
, object
);
154 struct dispatch_object_s
{
155 DISPATCH_STRUCT_HEADER(object
);
158 size_t _dispatch_object_debug_attr(dispatch_object_t dou
, char* buf
,
160 void *_dispatch_alloc(const void *vtable
, size_t size
);
161 void _dispatch_retain(dispatch_object_t dou
);
162 void _dispatch_release(dispatch_object_t dou
);
163 void _dispatch_xref_dispose(dispatch_object_t dou
);
164 void _dispatch_dispose(dispatch_object_t dou
);
165 #if DISPATCH_COCOA_COMPAT
166 void *_dispatch_autorelease_pool_push(void);
167 void _dispatch_autorelease_pool_pop(void *context
);
170 typedef struct _os_object_class_s
{
171 _OS_OBJECT_CLASS_HEADER();
172 } _os_object_class_s
;
174 typedef struct _os_object_s
{
176 const _os_object_class_s
*os_obj_isa
,
181 void _os_object_init(void);
182 unsigned long _os_object_retain_count(_os_object_t obj
);
183 bool _os_object_retain_weak(_os_object_t obj
);
184 bool _os_object_allows_weak_reference(_os_object_t obj
);
185 void _os_object_dispose(_os_object_t obj
);
186 void _os_object_xref_dispose(_os_object_t obj
);