Implement DBUS timeout functions
This commit is contained in:
parent
99ea6c08a7
commit
8e665ffedc
27
glfw/backend_utils.c
vendored
27
glfw/backend_utils.c
vendored
@ -12,11 +12,25 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#define ppoll pollts
|
||||
#endif
|
||||
|
||||
static inline double
|
||||
monotonic() {
|
||||
struct timespec ts = {0};
|
||||
#ifdef CLOCK_HIGHRES
|
||||
clock_gettime(CLOCK_HIGHRES, &ts);
|
||||
#elif CLOCK_MONOTONIC_RAW
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
|
||||
}
|
||||
|
||||
void
|
||||
update_fds(EventLoopData *eld) {
|
||||
eld->fds_count = 0;
|
||||
@ -73,7 +87,6 @@ toggleWatch(EventLoopData *eld, id_type watch_id, int enabled) {
|
||||
}
|
||||
|
||||
static id_type timer_counter = 0;
|
||||
extern double glfwGetTime(void);
|
||||
|
||||
static int
|
||||
compare_timers(const void *a_, const void *b_) {
|
||||
@ -91,7 +104,7 @@ addTimer(EventLoopData *eld, double interval, int enabled, timer_callback_func c
|
||||
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) return 0;
|
||||
Timer *t = eld->timers + eld->timers_count++;
|
||||
t->interval = interval;
|
||||
t->trigger_at = enabled ? glfwGetTime() + interval : DBL_MAX;
|
||||
t->trigger_at = enabled ? monotonic() + interval : DBL_MAX;
|
||||
t->callback = cb;
|
||||
t->callback_data = cb_data;
|
||||
t->id = ++timer_counter;
|
||||
@ -108,7 +121,7 @@ void
|
||||
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
|
||||
for (nfds_t i = 0; i < eld->timers_count; i++) {
|
||||
if (eld->timers[i].id == timer_id) {
|
||||
double trigger_at = enabled ? (glfwGetTime() + eld->timers[i].interval) : DBL_MAX;
|
||||
double trigger_at = enabled ? (monotonic() + eld->timers[i].interval) : DBL_MAX;
|
||||
if (trigger_at != eld->timers[i].trigger_at) {
|
||||
eld->timers[i].trigger_at = trigger_at;
|
||||
update_timers(eld);
|
||||
@ -133,7 +146,7 @@ double
|
||||
prepareForPoll(EventLoopData *eld, double timeout) {
|
||||
for (nfds_t i = 0; i < eld->fds_count; i++) eld->fds[i].revents = 0;
|
||||
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return timeout;
|
||||
double now = glfwGetTime(), next_repeat_at = eld->timers[0].trigger_at;
|
||||
double now = monotonic(), next_repeat_at = eld->timers[0].trigger_at;
|
||||
if (timeout < 0 || now + timeout > next_repeat_at) {
|
||||
timeout = next_repeat_at <= now ? 0 : next_repeat_at - now;
|
||||
}
|
||||
@ -165,7 +178,7 @@ dispatchTimers(EventLoopData *eld) {
|
||||
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0;
|
||||
static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
|
||||
unsigned num_dispatches = 0;
|
||||
double now = glfwGetTime();
|
||||
double now = monotonic();
|
||||
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at < DBL_MAX; i++) {
|
||||
if (eld->timers[i].trigger_at <= now) {
|
||||
eld->timers[i].trigger_at = now + eld->timers[i].interval;
|
||||
@ -201,7 +214,7 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
||||
int read_ok = 0;
|
||||
timeout = prepareForPoll(eld, timeout);
|
||||
int result;
|
||||
double end_time = glfwGetTime() + timeout;
|
||||
double end_time = monotonic() + timeout;
|
||||
|
||||
while(1) {
|
||||
if (timeout >= 0) {
|
||||
@ -212,7 +225,7 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
||||
read_ok = eld->watches[0].ready;
|
||||
break;
|
||||
}
|
||||
timeout = end_time - glfwGetTime();
|
||||
timeout = end_time - monotonic();
|
||||
if (timeout <= 0) break;
|
||||
if (result < 0 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||
break;
|
||||
|
||||
42
glfw/dbus_glfw.c
vendored
42
glfw/dbus_glfw.c
vendored
@ -76,6 +76,7 @@ add_dbus_watch(DBusWatch *watch, void *data) {
|
||||
if (!watch_id) return FALSE;
|
||||
id_type *idp = malloc(sizeof(id_type));
|
||||
if (!idp) return FALSE;
|
||||
*idp = watch_id;
|
||||
dbus_watch_set_data(watch, idp, free);
|
||||
return TRUE;
|
||||
}
|
||||
@ -92,6 +93,41 @@ toggle_dbus_watch(DBusWatch *watch, void *data) {
|
||||
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
|
||||
}
|
||||
|
||||
static void
|
||||
on_dbus_timer_ready(id_type timer_id, void *data) {
|
||||
DBusTimeout *t = (DBusTimeout*)data;
|
||||
dbus_timeout_handle(t);
|
||||
}
|
||||
|
||||
|
||||
static dbus_bool_t
|
||||
add_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
int enabled = dbus_timeout_get_enabled(timeout) ? 1 : 0;
|
||||
double interval = ((double)dbus_timeout_get_interval(timeout)) / 1000.0;
|
||||
if (interval < 0) return FALSE;
|
||||
id_type timer_id = addTimer(dbus_data->eld, interval, enabled, on_dbus_timer_ready, timeout);
|
||||
if (!timer_id) return FALSE;
|
||||
id_type *idp = malloc(sizeof(id_type));
|
||||
if (!idp) return FALSE;
|
||||
*idp = timer_id;
|
||||
dbus_timeout_set_data(timeout, idp, free);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) removeTimer(dbus_data->eld, *idp);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
|
||||
}
|
||||
|
||||
|
||||
DBusConnection*
|
||||
glfw_dbus_connect_to(const char *path, const char* err_msg) {
|
||||
DBusError err;
|
||||
@ -114,6 +150,12 @@ glfw_dbus_connect_to(const char *path, const char* err_msg) {
|
||||
dbus_connection_unref(ans);
|
||||
return NULL;
|
||||
}
|
||||
if (!dbus_connection_set_timeout_functions(ans, add_dbus_timeout, remove_dbus_timeout, toggle_dbus_timeout, NULL, NULL)) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS timeout functions on connection to: %s", path);
|
||||
dbus_connection_close(ans);
|
||||
dbus_connection_unref(ans);
|
||||
return NULL;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user