diff options
Diffstat (limited to 'src/libmowgli/eventloop/eventloop.h')
-rw-r--r-- | src/libmowgli/eventloop/eventloop.h | 148 |
1 files changed, 126 insertions, 22 deletions
diff --git a/src/libmowgli/eventloop/eventloop.h b/src/libmowgli/eventloop/eventloop.h index 4c07b27..42a257c 100644 --- a/src/libmowgli/eventloop/eventloop.h +++ b/src/libmowgli/eventloop/eventloop.h @@ -21,6 +21,13 @@ #ifndef __MOWGLI_EVENTLOOP_EVENTLOOP_H__ #define __MOWGLI_EVENTLOOP_EVENTLOOP_H__ +#ifdef MOWGLI_OS_OSX + +# include <mach/mach.h> +# include <mach/mach_time.h> + +#endif + #ifndef _WIN32 typedef int mowgli_descriptor_t; @@ -31,13 +38,15 @@ typedef SOCKET mowgli_descriptor_t; #endif -typedef enum { +typedef enum +{ MOWGLI_EVENTLOOP_TYPE_POLLABLE, MOWGLI_EVENTLOOP_TYPE_HELPER, MOWGLI_EVENTLOOP_TYPE_ERROR = -1 } mowgli_eventloop_io_type_t; -typedef struct { +typedef struct +{ mowgli_eventloop_io_type_t type; } mowgli_eventloop_io_obj_t; @@ -48,7 +57,8 @@ typedef struct _mowgli_helper mowgli_eventloop_helper_proc_t; typedef struct _mowgli_linebuf mowgli_linebuf_t; -typedef enum { +typedef enum +{ MOWGLI_EVENTLOOP_IO_READ, MOWGLI_EVENTLOOP_IO_WRITE, MOWGLI_EVENTLOOP_IO_ERROR = -1 @@ -57,7 +67,8 @@ typedef enum { typedef void mowgli_eventloop_io_t; /* checked casts */ -static inline mowgli_eventloop_pollable_t *mowgli_eventloop_io_pollable(mowgli_eventloop_io_t *io) +static inline mowgli_eventloop_pollable_t * +mowgli_eventloop_io_pollable(mowgli_eventloop_io_t *io) { mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io; @@ -67,7 +78,8 @@ static inline mowgli_eventloop_pollable_t *mowgli_eventloop_io_pollable(mowgli_e return (mowgli_eventloop_pollable_t *) io; } -static inline mowgli_eventloop_helper_proc_t *mowgli_eventloop_io_helper(mowgli_eventloop_io_t *io) +static inline mowgli_eventloop_helper_proc_t * +mowgli_eventloop_io_helper(mowgli_eventloop_io_t *io) { mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io; @@ -77,7 +89,8 @@ static inline mowgli_eventloop_helper_proc_t *mowgli_eventloop_io_helper(mowgli_ return (mowgli_eventloop_helper_proc_t *) io; } -static inline mowgli_eventloop_io_type_t mowgli_eventloop_io_type(mowgli_eventloop_io_t *io) +static inline mowgli_eventloop_io_type_t +mowgli_eventloop_io_type(mowgli_eventloop_io_t *io) { mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io; @@ -86,9 +99,10 @@ static inline mowgli_eventloop_io_type_t mowgli_eventloop_io_type(mowgli_eventlo return obj->type; } -typedef void mowgli_eventloop_io_cb_t(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata); +typedef void mowgli_eventloop_io_cb_t (mowgli_eventloop_t * eventloop, mowgli_eventloop_io_t * io, mowgli_eventloop_io_dir_t dir, void *userdata); -struct _mowgli_pollable { +struct _mowgli_pollable +{ mowgli_eventloop_io_obj_t type; mowgli_descriptor_t fd; @@ -106,7 +120,8 @@ struct _mowgli_pollable { mowgli_eventloop_t *eventloop; }; -typedef struct { +typedef struct +{ void (*timeout_once)(mowgli_eventloop_t *eventloop, int timeout); void (*run_once)(mowgli_eventloop_t *eventloop); void (*pollsetup)(mowgli_eventloop_t *eventloop); @@ -116,7 +131,8 @@ typedef struct { void (*destroy)(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable); } mowgli_eventloop_ops_t; -struct _mowgli_eventloop { +struct _mowgli_eventloop +{ time_t currtime; time_t deadline; @@ -131,41 +147,124 @@ struct _mowgli_eventloop { bool death_requested; void *data; + + time_t epochbias; }; -typedef void mowgli_event_dispatch_func_t(void *userdata); +typedef void mowgli_event_dispatch_func_t (void *userdata); -typedef struct { +typedef struct +{ mowgli_node_t node; mowgli_event_dispatch_func_t *func; void *arg; const char *name; time_t frequency; - time_t when; + time_t deadline; bool active; } mowgli_eventloop_timer_t; -static inline void mowgli_eventloop_set_time(mowgli_eventloop_t *eventloop, time_t newtime) +static inline void +mowgli_eventloop_set_time(mowgli_eventloop_t *eventloop, time_t newtime) { return_if_fail(eventloop != NULL); eventloop->currtime = newtime; } -static inline time_t mowgli_eventloop_get_time(mowgli_eventloop_t *eventloop) +static inline time_t +mowgli_eventloop_get_time(mowgli_eventloop_t *eventloop) { return_val_if_fail(eventloop != NULL, 0); - return eventloop->currtime; + return eventloop->epochbias + eventloop->currtime; } -static inline void mowgli_eventloop_synchronize(mowgli_eventloop_t *eventloop) +static inline void +mowgli_eventloop_synchronize(mowgli_eventloop_t *eventloop) { - mowgli_eventloop_set_time(eventloop, time(NULL)); + long long time_; + +#if defined(CLOCK_MONOTONIC) + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC, &tp); + time_ = tp.tv_sec; +#elif defined(CLOCK_HIGHRES) + struct timespec tp; + + clock_gettime(CLOCK_HIGHRES, &tp); + time_ = tp.tv_sec; +#elif defined(MOWGLI_OS_WIN) + static ULONGLONG (CALLBACK *GetTickCount64)(void) = NULL; + static OSVERSIONINFOEX *winver = NULL; + static bool load_err = false; + + if (winver == NULL) + { + winver = mowgli_alloc(sizeof(OSVERSIONINFOEX)); + winver->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if (!GetVersionEx((OSVERSIONINFO *) winver)) + { + mowgli_free(winver); + winver = NULL; /* FIXME */ + } + } + + if (winver && (winver->dwMajorVersion >= 6)) + { + if ((GetTickCount64 == NULL) && !load_err) + { + HINSTANCE hKernel32; + + hKernel32 = GetModuleHandle("KERNEL32"); + GetTickCount64 = GetProcAddress(hKernel32, "GetTickCount64"); + + if (GetTickCount64 == NULL) + load_err = true; + } + + if (load_err) + { + time_ = time(NULL); + } + else + { + soft_assert(GetTickCount64 != NULL); + + time_ = (int) (GetTickCount64() * 1e-3); + } + } + else + { + time_ = time(NULL); + } + +#elif defined(MOWGLI_OS_OSX) + static mach_timebase_info_data_t timebase; + + if (timebase.denom == 0) + mach_timebase_info(&timebase); + + time_ = (int) (mach_absolute_time() * timebase.numer / timebase.denom * 1e-9); +#else + time_ = time(NULL); +#endif + mowgli_eventloop_set_time(eventloop, (time_t) time_); +} + +/* Sets the bias of eventloop->currtime relative to Jan 1 00:00:00 1970 */ +static inline void +mowgli_eventloop_calibrate(mowgli_eventloop_t *eventloop) +{ + mowgli_eventloop_synchronize(eventloop); + eventloop->epochbias = time(NULL) - eventloop->currtime; } -static inline bool mowgli_eventloop_ignore_errno(int error) +static inline bool +mowgli_eventloop_ignore_errno(int error) { switch (error) { @@ -178,6 +277,9 @@ static inline bool mowgli_eventloop_ignore_errno(int error) #if defined(EAGAIN) && (EWOULDBLOCK != EAGAIN) case EAGAIN: #endif +#ifdef ETIME + case ETIME: +#endif #ifdef EINTR case EINTR: #endif @@ -198,9 +300,10 @@ static inline bool mowgli_eventloop_ignore_errno(int error) return false; } -typedef void mowgli_eventloop_helper_start_fn_t(mowgli_eventloop_helper_proc_t *helper, void *userdata); +typedef void mowgli_eventloop_helper_start_fn_t (mowgli_eventloop_helper_proc_t * helper, void *userdata); -struct _mowgli_helper { +struct _mowgli_helper +{ mowgli_eventloop_io_obj_t type; mowgli_process_t *child; @@ -254,6 +357,7 @@ extern mowgli_eventloop_pollable_t *mowgli_pollable_create(mowgli_eventloop_t *e extern void mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable); extern void mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function); extern void mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool nonblocking); +extern void mowgli_pollable_set_cloexec(mowgli_eventloop_pollable_t *pollable, bool cloexec); +extern void mowgli_pollable_trigger(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir); #endif - |