void sync_array_wait_event( /*==================*/ sync_array_t* arr, /* in: wait array */ ulint index) /* in: index of the reserved cell */ { sync_cell_t* cell; os_event_t event; ut_a(arr); sync_array_enter(arr); cell = sync_array_get_nth_cell(arr, index); ut_a(cell->wait_object); ut_a(!cell->waiting); ut_ad(os_thread_get_curr_id() == cell->thread); if (cell->request_type == SYNC_MUTEX) { event = ((mutex_t*) cell->wait_object)->event; #ifdef __WIN__ /* On windows if the thread about to wait is the one which has set the state of the rw_lock to RW_LOCK_WAIT_EX, then it waits on a special event i.e.: wait_ex_event. */ } else if (cell->request_type == RW_LOCK_WAIT_EX) { event = ((rw_lock_t*) cell->wait_object)->wait_ex_event; #endif } else { event = ((rw_lock_t*) cell->wait_object)->event; } cell->waiting = TRUE; #ifdef UNIV_SYNC_DEBUG /* We use simple enter to the mutex below, because if we cannot acquire it at once, mutex_enter would call recursively sync_array routines, leading to trouble. rw_lock_debug_mutex freezes the debug lists. */ rw_lock_debug_mutex_enter(); if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) { fputs("########################################\n", stderr); ut_error; } rw_lock_debug_mutex_exit(); #endif sync_array_exit(arr); os_event_wait_low(event, cell->signal_count); sync_array_free_cell(arr, index); }
/******************************************************************//** This function should be called when a thread starts to wait on a wait array cell. In the debug version this function checks if the wait for a semaphore will result in a deadlock, in which case prints info and asserts. */ UNIV_INTERN void sync_array_wait_event( /*==================*/ sync_array_t* arr, /*!< in: wait array */ ulint index) /*!< in: index of the reserved cell */ { sync_cell_t* cell; os_event_t event; ut_a(arr); sync_array_enter(arr); cell = sync_array_get_nth_cell(arr, index); ut_a(cell->wait_object); ut_a(!cell->waiting); ut_ad(os_thread_get_curr_id() == cell->thread); event = sync_cell_get_event(cell); cell->waiting = TRUE; #ifdef UNIV_SYNC_DEBUG /* We use simple enter to the mutex below, because if we cannot acquire it at once, mutex_enter would call recursively sync_array routines, leading to trouble. rw_lock_debug_mutex freezes the debug lists. */ rw_lock_debug_mutex_enter(); if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) { fputs("########################################\n", stderr); ut_error; } rw_lock_debug_mutex_exit(); #endif sync_array_exit(arr); os_event_wait_low(event, cell->signal_count); sync_array_free_cell(arr, index); }
void sync_array_validate( /*================*/ sync_array_t* arr) /* in: sync wait array */ { ulint i; sync_cell_t* cell; ulint count = 0; sync_array_enter(arr); for (i = 0; i < arr->n_cells; i++) { cell = sync_array_get_nth_cell(arr, i); if (cell->wait_object != NULL) { count++; } } ut_a(count == arr->n_reserved); sync_array_exit(arr); }
/******************************************************************//** Reserves a wait array cell for waiting for an object. The event of the cell is reset to nonsignalled state. */ UNIV_INTERN void sync_array_reserve_cell( /*====================*/ sync_array_t* arr, /*!< in: wait array */ void* object, /*!< in: pointer to the object to wait for */ ulint type, /*!< in: lock request type */ const char* file, /*!< in: file where requested */ ulint line, /*!< in: line where requested */ ulint* index) /*!< out: index of the reserved cell */ { sync_cell_t* cell; os_event_t event; ulint i; ut_a(object); ut_a(index); sync_array_enter(arr); arr->res_count++; /* Reserve a new cell. */ for (i = 0; i < arr->n_cells; i++) { cell = sync_array_get_nth_cell(arr, i); if (cell->wait_object == NULL) { cell->waiting = FALSE; cell->wait_object = object; if (type == SYNC_MUTEX) { cell->old_wait_mutex = object; } else { cell->old_wait_rw_lock = object; } cell->request_type = type; cell->file = file; cell->line = line; arr->n_reserved++; *index = i; sync_array_exit(arr); /* Make sure the event is reset and also store the value of signal_count at which the event was reset. */ event = sync_cell_get_event(cell); cell->signal_count = os_event_reset(event); cell->reservation_time = time(NULL); cell->thread = os_thread_get_curr_id(); return; } } ut_error; /* No free cell found */ return; }