summaryrefslogtreecommitdiff
path: root/src/libmowgli/eventloop/eventloop.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmowgli/eventloop/eventloop.h')
-rw-r--r--src/libmowgli/eventloop/eventloop.h148
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
-