]> git.saurik.com Git - apple/libdispatch.git/blobdiff - src/source_internal.h
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / src / source_internal.h
index e7126dbb3cf1c765ed42db4a19cd261e50b87153..55b81e78775aaada4adcc34a08cd9ed84338b2e7 100644 (file)
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_APACHE_LICENSE_HEADER_START@
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- * 
+ *
  * @APPLE_APACHE_LICENSE_HEADER_END@
  */
 
 #include <dispatch/base.h> // for HeaderDoc
 #endif
 
-struct dispatch_source_vtable_s {
-       DISPATCH_VTABLE_HEADER(dispatch_source_s);
+enum {
+       /* DISPATCH_TIMER_STRICT 0x1 */
+       /* DISPATCH_TIMER_BACKGROUND = 0x2, */
+       DISPATCH_TIMER_CLOCK_MACH = 0x4,
+       DISPATCH_TIMER_INTERVAL = 0x8,
+       DISPATCH_TIMER_AFTER = 0x10,
+       /* DISPATCH_INTERVAL_UI_ANIMATION = 0x20 */
 };
 
-extern const struct dispatch_source_vtable_s _dispatch_source_kevent_vtable;
+DISPATCH_ALWAYS_INLINE
+static inline unsigned int
+_dispatch_source_timer_idx(dispatch_unote_t du)
+{
+       uint32_t clock, qos = 0, fflags = du._dt->du_fflags;
 
-struct dispatch_kevent_s {
-       TAILQ_ENTRY(dispatch_kevent_s) dk_list;
-       TAILQ_HEAD(, dispatch_source_s) dk_sources;
-       struct kevent dk_kevent;
-};
+       dispatch_assert(DISPATCH_CLOCK_MACH == 1);
+       dispatch_assert(DISPATCH_CLOCK_WALL == 0);
+       clock = (fflags & DISPATCH_TIMER_CLOCK_MACH) / DISPATCH_TIMER_CLOCK_MACH;
+
+#if DISPATCH_HAVE_TIMER_QOS
+       dispatch_assert(DISPATCH_TIMER_STRICT == DISPATCH_TIMER_QOS_CRITICAL);
+       dispatch_assert(DISPATCH_TIMER_BACKGROUND == DISPATCH_TIMER_QOS_BACKGROUND);
+       qos = fflags & (DISPATCH_TIMER_STRICT | DISPATCH_TIMER_BACKGROUND);
+       // flags are normalized so this should never happen
+       dispatch_assert(qos < DISPATCH_TIMER_QOS_COUNT);
+#endif
 
-typedef struct dispatch_kevent_s *dispatch_kevent_t;
+       return DISPATCH_TIMER_INDEX(clock, qos);
+}
 
-struct dispatch_timer_source_s {
-       uint64_t target;
-       uint64_t start;
-       uint64_t interval;
-       uint64_t leeway;
-       uint64_t flags; // dispatch_timer_flags_t
-};
+#define _DISPATCH_SOURCE_HEADER(refs) \
+       DISPATCH_QUEUE_HEADER(refs); \
+       unsigned int \
+               ds_is_installed:1, \
+               dm_needs_mgr:1, \
+               dm_connect_handler_called:1, \
+               dm_uninstalled:1, \
+               dm_cancel_handler_called:1, \
+               dm_is_xpc:1
 
-#define DSF_CANCELED 1u // cancellation has been requested
+#define DISPATCH_SOURCE_HEADER(refs) \
+       struct dispatch_source_s _as_ds[0]; \
+       _DISPATCH_SOURCE_HEADER(refs)
 
+DISPATCH_CLASS_DECL_BARE(source);
+_OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(dispatch_source, dispatch_object);
+
+#ifndef __cplusplus
 struct dispatch_source_s {
-       DISPATCH_STRUCT_HEADER(dispatch_source_s, dispatch_source_vtable_s);
-       DISPATCH_QUEUE_HEADER;
-       // Instruments always copies DISPATCH_QUEUE_MIN_LABEL_SIZE, which is 64,
-       // so the remainder of the structure must be big enough
-       union {
-               char _ds_pad[DISPATCH_QUEUE_MIN_LABEL_SIZE];
-               struct {
-                       char dq_label[8];
-                       dispatch_kevent_t ds_dkev;
-                       
-                       dispatch_source_handler_function_t ds_handler_func;
-                       void *ds_handler_ctxt;
-                       
-                       void *ds_cancel_handler;
-                       
-                       unsigned int ds_is_level:1,
-                       ds_is_adder:1,
-                       ds_is_installed:1,
-                       ds_needs_rearm:1,
-                       ds_is_armed:1,
-                       ds_is_legacy:1,
-                       ds_cancel_is_block:1,
-                       ds_handler_is_block:1;
-
-                       unsigned int ds_atomic_flags;
-
-                       unsigned long ds_data;
-                       unsigned long ds_pending_data;
-                       unsigned long ds_pending_data_mask;
-                       
-                       TAILQ_ENTRY(dispatch_source_s) ds_list;
-                       
-                       unsigned long ds_ident_hack;
-                       
-                       struct dispatch_timer_source_s ds_timer;
-               };
-       };
-};
+       _DISPATCH_SOURCE_HEADER(source);
+       uint64_t ds_data DISPATCH_ATOMIC64_ALIGN;
+       uint64_t ds_pending_data DISPATCH_ATOMIC64_ALIGN;
+} DISPATCH_ATOMIC64_ALIGN;
+
+// Extracts source data from the ds_data field
+#define DISPATCH_SOURCE_GET_DATA(d) ((d) & 0xFFFFFFFF)
+
+// Extracts status from the ds_data field
+#define DISPATCH_SOURCE_GET_STATUS(d) ((d) >> 32)
+
+// Combine data and status for the ds_data field
+#define DISPATCH_SOURCE_COMBINE_DATA_AND_STATUS(data, status) \
+               ((((uint64_t)(status)) << 32) | (data))
+
+#endif // __cplusplus
+
+void _dispatch_source_refs_register(dispatch_source_t ds,
+               dispatch_wlh_t wlh, dispatch_priority_t bp);
+void _dispatch_source_refs_unregister(dispatch_source_t ds, uint32_t options);
+void _dispatch_source_xref_dispose(dispatch_source_t ds);
+void _dispatch_source_dispose(dispatch_source_t ds, bool *allow_free);
+void _dispatch_source_finalize_activation(dispatch_source_t ds,
+               bool *allow_resume);
+void _dispatch_source_invoke(dispatch_source_t ds,
+               dispatch_invoke_context_t dic, dispatch_invoke_flags_t flags);
+void _dispatch_source_wakeup(dispatch_source_t ds, dispatch_qos_t qos,
+               dispatch_wakeup_flags_t flags);
+void _dispatch_source_merge_evt(dispatch_unote_t du, uint32_t flags,
+               uintptr_t data, uintptr_t status, pthread_priority_t pp);
+size_t _dispatch_source_debug(dispatch_source_t ds, char* buf, size_t bufsiz);
 
+DISPATCH_EXPORT // for firehose server
+void _dispatch_source_merge_data(dispatch_source_t ds, pthread_priority_t pp,
+               unsigned long val);
 
-void _dispatch_source_legacy_xref_release(dispatch_source_t ds);
+void _dispatch_mgr_queue_push(dispatch_queue_t dq, dispatch_object_t dou,
+               dispatch_qos_t qos);
+void _dispatch_mgr_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos,
+               dispatch_wakeup_flags_t flags);
+void _dispatch_mgr_thread(dispatch_queue_t dq, dispatch_invoke_context_t dic,
+               dispatch_invoke_flags_t flags);
+#if DISPATCH_USE_KEVENT_WORKQUEUE
+void _dispatch_kevent_worker_thread(dispatch_kevent_t *events,
+               int *nevents);
+#endif // DISPATCH_USE_KEVENT_WORKQUEUE
 
 #endif /* __DISPATCH_SOURCE_INTERNAL__ */