/**********************************************************//** Waits for an event object until it is in the signaled state. If srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the waiting thread when the event becomes signaled (or immediately if the event is already in the signaled state). Typically, if the event has been signalled after the os_event_reset() we'll return immediately because event->is_set == TRUE. There are, however, situations (e.g.: sync_array code) where we may lose this information. For example: thread A calls os_event_reset() thread B calls os_event_set() [event->is_set == TRUE] thread C calls os_event_reset() [event->is_set == FALSE] thread A calls os_event_wait() [infinite wait!] thread C calls os_event_wait() [infinite wait!] Where such a scenario is possible, to avoid infinite wait, the value returned by os_event_reset() should be passed in as reset_sig_count. */ UNIV_INTERN void os_event_wait_low( /*==============*/ os_event_t event, /*!< in: event to wait */ ib_int64_t reset_sig_count)/*!< in: zero or the value returned by previous call of os_event_reset(). */ { #ifdef __WIN__ DWORD err; ut_a(event); UT_NOT_USED(reset_sig_count); /* Specify an infinite time limit for waiting */ err = WaitForSingleObject(event->handle, INFINITE); ut_a(err == WAIT_OBJECT_0); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { os_thread_exit(NULL); } #else ib_int64_t old_signal_count; os_fast_mutex_lock(&(event->os_mutex)); if (reset_sig_count) { old_signal_count = reset_sig_count; } else { old_signal_count = event->signal_count; } for (;;) { if (event->is_set == TRUE || event->signal_count != old_signal_count) { os_fast_mutex_unlock(&(event->os_mutex)); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { os_thread_exit(NULL); } /* Ok, we may return */ return; } pthread_cond_wait(&(event->cond_var), &(event->os_mutex)); /* Solaris manual said that spurious wakeups may occur: we have to check if the event really has been signaled after we came here to wait */ } #endif }
/************************************************************************ I/o-handler thread function. */ static os_thread_ret_t io_handler_thread( /*==============*/ void* arg) { ulint segment; ulint i; segment = *((ulint*)arg); #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment, os_thread_pf(os_thread_get_curr_id())); #endif for (i = 0;; i++) { fil_aio_wait(segment); mutex_enter(&ios_mutex); ios++; mutex_exit(&ios_mutex); } /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. The thread actually never comes here because it is exited in an os_event_wait(). */ os_thread_exit(NULL); OS_THREAD_DUMMY_RETURN; }
/**********************************************************//** Waits for any event in an OS native event array. Returns if even a single one is signaled or becomes signaled. @return index of the event which was signaled */ UNIV_INTERN ulint os_event_wait_multiple( /*===================*/ ulint n, /*!< in: number of events in the array */ os_native_event_t* native_event_array) /*!< in: pointer to an array of event handles */ { DWORD index; ut_a(native_event_array); ut_a(n > 0); index = WaitForMultipleObjects((DWORD) n, native_event_array, FALSE, /* Wait for any 1 event */ INFINITE); /* Infinite wait time limit */ ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */ ut_a(index < WAIT_OBJECT_0 + n); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { os_thread_exit(NULL); } return(index - WAIT_OBJECT_0); }
GPrivate void gcmon_thread_exit() { if (gpThread != NULL) { os_thread_exit(gpThread); gpThread = NULL; } }