/* Function: al_join_thread */ void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value) { ASSERT(thread); /* If al_join_thread() is called soon after al_start_thread(), the thread * function may not yet have noticed the STARTING state and executed the * user's thread function. Hence we must wait until the thread enters the * STARTED state. */ while (thread->thread_state == THREAD_STATE_STARTING) { al_rest(0.001); } switch (thread->thread_state) { case THREAD_STATE_CREATED: /* fall through */ case THREAD_STATE_STARTED: _al_mutex_lock(&thread->mutex); thread->thread_state = THREAD_STATE_JOINING; _al_cond_broadcast(&thread->cond); _al_mutex_unlock(&thread->mutex); _al_cond_destroy(&thread->cond); _al_mutex_destroy(&thread->mutex); _al_thread_join(&thread->thread); thread->thread_state = THREAD_STATE_JOINED; break; case THREAD_STATE_STARTING: ASSERT(thread->thread_state != THREAD_STATE_STARTING); break; case THREAD_STATE_JOINING: ASSERT(thread->thread_state != THREAD_STATE_JOINING); break; case THREAD_STATE_JOINED: ASSERT(thread->thread_state != THREAD_STATE_JOINED); break; case THREAD_STATE_DESTROYED: ASSERT(thread->thread_state != THREAD_STATE_DESTROYED); break; case THREAD_STATE_DETACHED: ASSERT(thread->thread_state != THREAD_STATE_DETACHED); break; } if (ret_value) { *ret_value = thread->retval; } }
static void xglx_shutdown_system(void) { ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); if (sx->x11display) { /* Events thread only runs if we are connected to an X server. */ _al_thread_join(&sx->thread); } /* Close all open displays. */ while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); // Makes sure we wait for any commands sent to the X server when destroying the displays. // Should make sure we don't shutdown before modes are restored. if (sx->x11display) { XSync(sx->x11display, False); } _al_xsys_mmon_exit(sx); if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; ALLEGRO_DEBUG("xsys: close x11display.\n"); } if (sx->gfxdisplay) { /* XXX for some reason, crashes if both XCloseDisplay calls are made */ /* XCloseDisplay(sx->gfxdisplay); */ sx->gfxdisplay = None; } al_free(sx); }
static void xglx_shutdown_system(void) { ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); if (sx->have_xevents_thread) { _al_thread_join(&sx->xevents_thread); sx->have_xevents_thread = false; } /* Close all open displays. */ while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; al_destroy_display(d); } _al_vector_free(&s->displays); // Makes sure we wait for any commands sent to the X server when destroying the displays. // Should make sure we don't shutdown before modes are restored. if (sx->x11display) { XSync(sx->x11display, False); } _al_xsys_mmon_exit(sx); if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; ALLEGRO_DEBUG("xsys: close x11display.\n"); } if (sx->gfxdisplay) { XCloseDisplay(sx->gfxdisplay); sx->gfxdisplay = None; } al_free(sx); }
static void xglx_shutdown_system(void) { /* Close all open displays. */ ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); _al_thread_join(&sx->thread); while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); _al_xglx_free_mode_infos(sx); #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA _al_xsys_xinerama_exit(sx); #endif if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; } if (sx->gfxdisplay) { /* XXX for some reason, crashes if both XCloseDisplay calls are made */ /* XCloseDisplay(sx->gfxdisplay); */ sx->gfxdisplay = None; } _AL_FREE(sx); }