/******************************************************************//** Looks for a cell with the given thread id. @return pointer to cell or NULL if not found */ static sync_cell_t* sync_array_find_thread( /*===================*/ sync_array_t* arr, /*!< in: wait array */ os_thread_id_t thread) /*!< in: thread id */ { ulint i; sync_cell_t* cell; for (i = 0; i < arr->n_cells; i++) { cell = sync_array_get_nth_cell(arr, i); if (cell->wait_object != NULL && os_thread_eq(cell->thread, thread)) { return(cell); /* Found */ } } return(NULL); /* Not found */ }
/********************************************************************** Low-level function for acquiring an exclusive lock. */ UNIV_INLINE ulint rw_lock_x_lock_low( /*===============*/ /* out: RW_LOCK_NOT_LOCKED if did not succeed, RW_LOCK_EX if success, RW_LOCK_WAIT_EX, if got wait reservation */ rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { ut_ad(mutex_own(rw_lock_get_mutex(lock))); if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { if (rw_lock_get_reader_count(lock) == 0) { rw_lock_set_writer(lock, RW_LOCK_EX); lock->writer_thread = os_thread_get_curr_id(); lock->writer_count++; lock->pass = pass; #ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name, line); #endif lock->last_x_file_name = file_name; lock->last_x_line = (unsigned int) line; /* Locking succeeded, we may return */ return(RW_LOCK_EX); } else { /* There are readers, we have to wait */ rw_lock_set_writer(lock, RW_LOCK_WAIT_EX); lock->writer_thread = os_thread_get_curr_id(); lock->pass = pass; lock->writer_is_wait_ex = TRUE; #ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX, file_name, line); #endif return(RW_LOCK_WAIT_EX); } } else if ((rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX) && os_thread_eq(lock->writer_thread, os_thread_get_curr_id())) { if (rw_lock_get_reader_count(lock) == 0) { rw_lock_set_writer(lock, RW_LOCK_EX); lock->writer_count++; lock->pass = pass; lock->writer_is_wait_ex = FALSE; #ifdef UNIV_SYNC_DEBUG rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX); rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name, line); #endif lock->last_x_file_name = file_name; lock->last_x_line = (unsigned int) line; /* Locking succeeded, we may return */ return(RW_LOCK_EX); } return(RW_LOCK_WAIT_EX); } else if ((rw_lock_get_writer(lock) == RW_LOCK_EX) && os_thread_eq(lock->writer_thread, os_thread_get_curr_id()) && (lock->pass == 0) && (pass == 0)) { lock->writer_count++; #ifdef UNIV_SYNC_DEBUG rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name, line); #endif lock->last_x_file_name = file_name; lock->last_x_line = (unsigned int) line; /* Locking succeeded, we may return */ return(RW_LOCK_EX); } /* Locking did not succeed */ return(RW_LOCK_NOT_LOCKED); }