/* Function: al_get_thread_should_stop */ bool al_get_thread_should_stop(ALLEGRO_THREAD *thread) { ASSERT(thread); return _al_get_thread_should_stop(&thread->thread); }
static void xglx_background_thread(_AL_THREAD *self, void *arg) { ALLEGRO_SYSTEM_XGLX *s = arg; XEvent event; double last_reset_screensaver_time = 0.0; while (!_al_get_thread_should_stop(self)) { /* Note: * Most older X11 implementations are not thread-safe no matter what, so * we simply cannot sit inside a blocking XNextEvent from another thread * if another thread also uses X11 functions. * * The usual use of XNextEvent is to only call it from the main thread. We * could of course do this for A5, just needs some slight adjustments to * the events system (polling for an Allegro event would call a function * of the system driver). * * As an alternative, we can use locking. This however can never fully * work, as for example OpenGL implementations also will access X11, in a * way we cannot know and cannot control (and we can't require users to * only call graphics functions inside a lock). * * However, most X11 implementations are somewhat thread safe, and do * use locking quite a bit themselves, so locking mostly does work. * * (Yet another alternative might be to use a separate X11 display * connection for graphics output.) * */ _al_mutex_lock(&s->lock); while (XEventsQueued(s->x11display, QueuedAfterFlush)) { XNextEvent(s->x11display, &event); process_x11_event(s, event); } /* The Xlib manual is particularly useless about the XResetScreenSaver() * function. Nevertheless, this does seem to work to inhibit the native * screensaver facility. Probably it won't do anything for other * systems, though. */ if (s->inhibit_screensaver) { double now = al_current_time(); if (now - last_reset_screensaver_time > 10.0) { XResetScreenSaver(s->x11display); last_reset_screensaver_time = now; } } _al_mutex_unlock(&s->lock); /* If no X11 events are there, unlock so other threads can run. We use * a select call to wake up when as soon as anything is available on * the X11 connection - and just for safety also wake up 10 times * a second regardless. */ int x11_fd = ConnectionNumber(s->x11display); fd_set fdset; FD_ZERO(&fdset); FD_SET(x11_fd, &fdset); struct timeval small_time = {0, 100000}; /* 10 times a second */ select(x11_fd + 1, &fdset, NULL, NULL, &small_time); } }