[libdispatch-dev] [PATCH 12/17] extract source-type-specific initialization to per-type functions
Paolo Bonzini
bonzini at gnu.org
Sun Oct 18 08:04:12 PDT 2009
As a first step towards eliminating struct kevent from source.c,
some of the initialization is moved to separate functions. This
introduces a per-source-type function pointer that is called when
creating a source.
The code is not 100% equal, but the only difference is that an
assertion is delayed to after the full initialization---which is
arguably better.
---
src/source.c | 63 +++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/src/source.c b/src/source.c
index b4f769d..d41bbda 100644
--- a/src/source.c
+++ b/src/source.c
@@ -925,13 +925,29 @@ dispatch_source_attr_copy(dispatch_source_attr_t proto)
struct dispatch_source_type_s {
struct kevent ke;
uint64_t mask;
+ void (*init) (dispatch_source_t ds,
+ dispatch_source_type_t type,
+ uintptr_t handle,
+ unsigned long mask,
+ dispatch_queue_t q);
};
+static void dispatch_source_type_timer_init (dispatch_source_t ds,
+ dispatch_source_type_t type,
+ uintptr_t handle,
+ unsigned long mask,
+ dispatch_queue_t q)
+{
+ ds->ds_needs_rearm = true;
+ ds->ds_timer.flags = mask;
+}
+
const struct dispatch_source_type_s _dispatch_source_type_timer = {
.ke = {
.filter = DISPATCH_EVFILT_TIMER,
},
.mask = DISPATCH_TIMER_INTERVAL|DISPATCH_TIMER_ONESHOT|DISPATCH_TIMER_ABSOLUTE|DISPATCH_TIMER_WALL_CLOCK,
+ .init = dispatch_source_type_timer_init
};
const struct dispatch_source_type_s _dispatch_source_type_read = {
@@ -999,6 +1015,18 @@ const struct dispatch_source_type_s _dispatch_source_type_vfs = {
};
#ifdef HAVE_MACH
+
+static void dispatch_source_type_mach_send_init (dispatch_source_t ds,
+ dispatch_source_type_t type,
+ uintptr_t handle,
+ unsigned long mask,
+ dispatch_queue_t q)
+{
+ static dispatch_once_t pred;
+ ds->ds_is_level = false;
+ dispatch_once_f(&pred, NULL, _dispatch_mach_notify_source_init);
+}
+
const struct dispatch_source_type_s _dispatch_source_type_mach_send = {
.ke = {
.filter = EVFILT_MACHPORT,
@@ -1006,14 +1034,25 @@ const struct dispatch_source_type_s _dispatch_source_type_mach_send = {
.fflags = DISPATCH_MACHPORT_DEAD,
},
.mask = DISPATCH_MACH_SEND_DEAD,
+ .init = dispatch_source_type_mach_send_init
};
+static void dispatch_source_type_mach_recv_init (dispatch_source_t ds,
+ dispatch_source_type_t type,
+ uintptr_t handle,
+ unsigned long mask,
+ dispatch_queue_t q)
+{
+ ds->ds_is_level = false;
+}
+
const struct dispatch_source_type_s _dispatch_source_type_mach_recv = {
.ke = {
.filter = EVFILT_MACHPORT,
.flags = EV_DISPATCH,
.fflags = DISPATCH_MACHPORT_RECV,
},
+ .init = dispatch_source_type_mach_recv_init
};
#endif
@@ -1097,38 +1136,22 @@ dispatch_source_create(dispatch_source_type_t type,
ds->ds_dkev = dk;
ds->ds_pending_data_mask = dk->dk_kevent.fflags;
if ((EV_DISPATCH|EV_ONESHOT) & proto_kev->flags) {
-#ifdef HAVE_MACH
- if (proto_kev->filter != EVFILT_MACHPORT) {
- ds->ds_is_level = true;
- }
-#endif
+ ds->ds_is_level = true;
ds->ds_needs_rearm = true;
} else if (!(EV_CLEAR & proto_kev->flags)) {
// we cheat and use EV_CLEAR to mean a "flag thingy"
ds->ds_is_adder = true;
}
- // If its a timer source, it needs to be re-armed
- if (type->ke.filter == DISPATCH_EVFILT_TIMER) {
- ds->ds_needs_rearm = true;
+ // Some sources require special processing
+ if (type->init) {
+ type->init (ds, type, handle, mask, q);
}
-
dispatch_assert(!(ds->ds_is_level && ds->ds_is_adder));
#if DISPATCH_DEBUG
dispatch_debug(ds, __FUNCTION__);
#endif
- // Some sources require special processing
-#ifdef HAVE_MACH
- if (type == DISPATCH_SOURCE_TYPE_MACH_SEND) {
- static dispatch_once_t pred;
- dispatch_once_f(&pred, NULL, _dispatch_mach_notify_source_init);
- } else
-#endif
- if (type == DISPATCH_SOURCE_TYPE_TIMER) {
- ds->ds_timer.flags = mask;
- }
-
_dispatch_retain(ds->do_targetq);
return ds;
--
1.6.2.5
More information about the libdispatch-dev
mailing list