Revision: 153 http://trac.macosforge.org/projects/libdispatch/changeset/153 Author: robert@fledge.watson.org Date: 2009-11-14 08:53:08 -0800 (Sat, 14 Nov 2009) Log Message: ----------- Complete separation of kqueue-specific portions of source.c into source_kevent.c. This differs from the submitted patch in the following ways: conflicts with another submitted patch resolved, house style adopted in some additional places, and __linux__ struct kevent definition removed. Submitted by: Paolo Bonzini <bonzini@gnu.org> Modified Paths: -------------- trunk/src/kevent_internal.h trunk/src/source.c trunk/src/source_internal.h trunk/src/source_kevent.c Modified: trunk/src/kevent_internal.h =================================================================== --- trunk/src/kevent_internal.h 2009-11-13 14:18:10 UTC (rev 152) +++ trunk/src/kevent_internal.h 2009-11-14 16:53:08 UTC (rev 153) @@ -28,6 +28,7 @@ #define __DISPATCH_KEVENT_INTERNAL__ #include <internal.h> +#include <sys/event.h> struct dispatch_kevent_s { TAILQ_ENTRY(dispatch_kevent_s) dk_list; @@ -35,11 +36,6 @@ struct kevent dk_kevent; }; -#define DISPATCH_EVFILT_TIMER (-EVFILT_SYSCOUNT - 1) -#define DISPATCH_EVFILT_CUSTOM_ADD (-EVFILT_SYSCOUNT - 2) -#define DISPATCH_EVFILT_CUSTOM_OR (-EVFILT_SYSCOUNT - 3) -#define DISPATCH_EVFILT_SYSCOUNT (EVFILT_SYSCOUNT + 3) - extern const struct dispatch_source_vtable_s _dispatch_source_kevent_vtable; #if DISPATCH_DEBUG Modified: trunk/src/source.c =================================================================== --- trunk/src/source.c 2009-11-13 14:18:10 UTC (rev 152) +++ trunk/src/source.c 2009-11-14 16:53:08 UTC (rev 153) @@ -25,8 +25,6 @@ #endif #include <sys/mount.h> -#include "kevent_internal.h" - #ifndef DISPATCH_NO_LEGACY struct dispatch_source_attr_vtable_s { DISPATCH_VTABLE_HEADER(dispatch_source_attr_s); @@ -392,50 +390,19 @@ unsigned long mask, dispatch_queue_t q) { - const struct kevent *proto_kev = &type->ke; dispatch_source_t ds = NULL; static char source_label[sizeof(ds->dq_label)] = "source"; - dispatch_kevent_t dk = NULL; // input validation if (type == NULL || (mask & ~type->mask)) { goto out_bad; } - switch (type->ke.filter) { - case EVFILT_SIGNAL: - if (handle >= NSIG) { - goto out_bad; - } - break; - case EVFILT_FS: - case DISPATCH_EVFILT_CUSTOM_ADD: - case DISPATCH_EVFILT_CUSTOM_OR: - case DISPATCH_EVFILT_TIMER: - if (handle) { - goto out_bad; - } - break; - default: - break; - } - ds = calloc(1ul, sizeof(struct dispatch_source_s)); if (slowpath(!ds)) { goto out_bad; } - dk = calloc(1ul, sizeof(struct dispatch_kevent_s)); - if (slowpath(!dk)) { - goto out_bad; - } - dk->dk_kevent = *proto_kev; - dk->dk_kevent.ident = handle; - dk->dk_kevent.flags |= EV_ADD|EV_ENABLE; - dk->dk_kevent.fflags |= (uint32_t)mask; - dk->dk_kevent.udata = dk; - TAILQ_INIT(&dk->dk_sources); - // Initialize as a queue first, then override some settings below. _dispatch_queue_init((dispatch_queue_t)ds); memcpy(ds->dq_label, source_label, sizeof(source_label)); @@ -447,22 +414,10 @@ // do_targetq will be retained below, past point of no-return ds->do_targetq = q; - // Dispatch Source - ds->ds_ident_hack = dk->dk_kevent.ident; - ds->ds_dkev = dk; - ds->ds_pending_data_mask = dk->dk_kevent.fflags; - if ((EV_DISPATCH|EV_ONESHOT) & proto_kev->flags) { - 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 (slowpath(!type->init(ds, type, handle, mask, q))) { + goto out_bad; } - - // Some sources require special processing - if (type->init != NULL) { - type->init(ds, type, handle, mask, q); - } + dispatch_assert(!(ds->ds_is_level && ds->ds_is_adder)); #if DISPATCH_DEBUG dispatch_debug(ds, __FUNCTION__); @@ -473,7 +428,6 @@ out_bad: free(ds); - free(dk); return NULL; } Modified: trunk/src/source_internal.h =================================================================== --- trunk/src/source_internal.h 2009-11-13 14:18:10 UTC (rev 152) +++ trunk/src/source_internal.h 2009-11-14 16:53:08 UTC (rev 153) @@ -103,7 +103,6 @@ bool _dispatch_source_probe(dispatch_source_t ds); void _dispatch_source_dispose(dispatch_source_t ds); size_t _dispatch_source_debug(dispatch_source_t ds, char* buf, size_t bufsiz); -void _dispatch_source_merge_kevent(dispatch_source_t ds, const struct kevent *ke); void _dispatch_source_kevent_resume(dispatch_source_t ds, uint32_t new_flags, uint32_t del_flags); void _dispatch_kevent_merge(dispatch_source_t ds); @@ -113,7 +112,7 @@ struct dispatch_source_type_s { struct kevent ke; uint64_t mask; - void (*init) (dispatch_source_t ds, + bool (*init) (dispatch_source_t ds, dispatch_source_type_t type, uintptr_t handle, unsigned long mask, Modified: trunk/src/source_kevent.c =================================================================== --- trunk/src/source_kevent.c 2009-11-13 14:18:10 UTC (rev 152) +++ trunk/src/source_kevent.c 2009-11-14 16:53:08 UTC (rev 153) @@ -67,6 +67,7 @@ .dk_sources = TAILQ_HEAD_INITIALIZER(_dispatch_kevent_data_add.dk_sources), }; +static void _dispatch_source_merge_kevent(dispatch_source_t ds, const struct kevent *ke); static void _dispatch_kevent_resume(dispatch_kevent_t dk, uint32_t new_flags, uint32_t del_flags); #if HAVE_MACH static void _dispatch_kevent_machport_resume(dispatch_kevent_t dk, uint32_t new_flags, uint32_t del_flags); @@ -563,11 +564,65 @@ _dispatch_source_merge_kevent(ds, &kev); } -static void +static bool +dispatch_source_type_kevent_init(dispatch_source_t ds, dispatch_source_type_t type, uintptr_t handle, unsigned long mask, dispatch_queue_t q) +{ + const struct kevent *proto_kev = &type->ke; + dispatch_kevent_t dk = NULL; + + switch (type->ke.filter) { + case EVFILT_SIGNAL: + if (handle >= NSIG) { + return false; + } + break; + case EVFILT_FS: + case DISPATCH_EVFILT_CUSTOM_ADD: + case DISPATCH_EVFILT_CUSTOM_OR: + case DISPATCH_EVFILT_TIMER: + if (handle) { + return false; + } + break; + default: + break; + } + + dk = calloc(1ul, sizeof(struct dispatch_kevent_s)); + if (slowpath(!dk)) { + return false; + } + + dk->dk_kevent = *proto_kev; + dk->dk_kevent.ident = handle; + dk->dk_kevent.flags |= EV_ADD|EV_ENABLE; + dk->dk_kevent.fflags |= (uint32_t)mask; + dk->dk_kevent.udata = dk; + TAILQ_INIT(&dk->dk_sources); + + // Dispatch Source + ds->ds_ident_hack = dk->dk_kevent.ident; + ds->ds_dkev = dk; + ds->ds_pending_data_mask = dk->dk_kevent.fflags; + if ((EV_DISPATCH|EV_ONESHOT) & proto_kev->flags) { + 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; + } + return true; +} + +static bool dispatch_source_type_timer_init(dispatch_source_t ds, dispatch_source_type_t type, uintptr_t handle, unsigned long mask, dispatch_queue_t q) { + if (!dispatch_source_type_kevent_init(ds, type, handle, mask, q)) { + return false; + } ds->ds_needs_rearm = true; ds->ds_timer.flags = mask; + return true; } const struct dispatch_source_type_s _dispatch_source_type_timer = { @@ -583,6 +638,7 @@ .filter = EVFILT_READ, .flags = EV_DISPATCH, }, + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_write = { @@ -590,6 +646,7 @@ .filter = EVFILT_WRITE, .flags = EV_DISPATCH, }, + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_proc = { @@ -605,12 +662,14 @@ |NOTE_REAP #endif , + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_signal = { .ke = { .filter = EVFILT_SIGNAL, }, + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_vnode = { @@ -624,6 +683,7 @@ |NOTE_NONE #endif , + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_vfs = { @@ -640,17 +700,22 @@ |VQ_VERYLOWDISK #endif , + .init = dispatch_source_type_kevent_init, }; #if HAVE_MACH -static void +static bool 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; + if (!dispatch_source_type_kevent_init(ds, type, handle, mask, q)) { + return false; + } ds->ds_is_level = false; dispatch_once_f(&pred, NULL, _dispatch_mach_notify_source_init); + return true; } const struct dispatch_source_type_s _dispatch_source_type_mach_send = { @@ -663,10 +728,14 @@ .init = dispatch_source_type_mach_send_init, }; -static void +static bool 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) { + if (!dispatch_source_type_kevent_init(ds, type, handle, mask, q)) { + return false; + } ds->ds_is_level = false; + return true; } const struct dispatch_source_type_s _dispatch_source_type_mach_recv = { @@ -683,6 +752,7 @@ .ke = { .filter = DISPATCH_EVFILT_CUSTOM_ADD, }, + .init = dispatch_source_type_kevent_init, }; const struct dispatch_source_type_s _dispatch_source_type_data_or = { @@ -691,6 +761,7 @@ .flags = EV_CLEAR, .fflags = ~0, }, + .init = dispatch_source_type_kevent_init, }; // Updates the ordered list of timers based on next fire date for changes to ds.
participants (1)
-
source_changes@macosforge.org