Exemplo n.º 1
0
/******************************************************************//**
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 */
}
Exemplo n.º 2
0
/**********************************************************************
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);
}