mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 23:34:34 +01:00
1d7de700e2
Fixed BUG#19542 "InnoDB doesn't increase the Handler_read_prev couter". Fixed BUG#19609 "Case sensitivity of innodb_data_file_path gives stupid error". Fixed BUG#19727 "InnoDB crashed server and crashed tables are ot recoverable". Also: * Remove remnants of the obsolete concept of memoryfixing tables and indexes. * Remove unused dict_table_LRU_trim(). * Remove unused 'trx' parameter from dict_table_get_on_id_low(), dict_table_get(), dict_table_get_and_increment_handle_count(). * Add a normal linked list implementation. * Add a work queue implementation. * Add 'level' parameter to mutex_create() and rw_lock_create(). Remove mutex_set_level() and rw_lock_set_level(). * Rename SYNC_LEVEL_NONE to SYNC_LEVEL_VARYING. * Add support for bound ids in InnoDB's parser. * Define UNIV_BTR_DEBUG for enabling consistency checks of FIL_PAGE_NEXT and FIL_PAGE_PREV when accessing sibling pages of B-tree indexes. btr_validate_level(): Check the validity of the doubly linked list formed by FIL_PAGE_NEXT and FIL_PAGE_PREV. * Adapt InnoDB to the new tablename to filename encoding in MySQL 5.1. ut_print_name(), ut_print_name1(): Add parameter 'table_id' for distinguishing names of tables from other identifiers. New: innobase_convert_from_table_id(), innobase_convert_from_id(), innobase_convert_from_filename(), innobase_get_charset. dict_accept(), dict_scan_id(), dict_scan_col(), dict_scan_table_name(), dict_skip_word(), dict_create_foreign_constraints_low(): Add parameter 'cs' so that isspace() can be replaced with my_isspace(), whose operation depends on the connection character set. dict_scan_id(): Convert identifier to UTF-8. dict_str_starts_with_keyword(): New extern function, to replace dict_accept() in row_search_for_mysql(). mysql_get_identifier_quote_char(): Replaced with innobase_print_identifier(). ha_innobase::create(): Remove the thd->convert_strin() call. Pass the statement to InnoDB in the connection character set and let InnoDB convert the identifier to UTF-8. * Add max_row_size to dict_table_t. * btr0cur.c btr_copy_externally_stored_field(): Only set the 'offset' variable when needed. * buf0buf.c buf_page_io_complete(): Write to the error log if the page number or the space id o the disk do not match those in memory. Also write to the error log if a page was read from the doublewrite buffer. The doublewrite buffer should be only read by the lower-level function fil_io() at database startup. * dict0dict.c dict_scan_table_name(): Remove fallback to differently encoded name when the table is not found. The encoding is handled at a higher level. * ha_innodb.cc Increment statistic counter in ha_innobase::index_prev() (bug 19542). Add innobase_convert_string wrapper function and a new file ha_prototypes.h. innobase_print_identifier(): Remove TODO comment before calling get_quote_char_for_identifier(). That function apparently assumes the identifier to be encoded in UTF-8. * ibuf0ibuf.c|h ibuf_count_get(), ibuf_counts[], ibuf_count_inited(): Define these only #ifdef UNIV_IBUF_DEBUG. Previously, when compiled without UNIV_IBUF_DEBUG, invoking ibuf_count_get() would crash InnoDB. The function is only being called #ifdef UNIV_IBUF_DEBUG. * innodb.result Adjust the results for changes in the foreign key error messages. * mem0mem.c|h New: mem_heap_dup(), mem_heap_printf(), mem_heap_cat(). * os0file.c Check the page trailers also after writing to disk. This improves chances of diagnosing bug 18886. os_file_check_page_trailers(): New function for checking that the two copies of the LSN stamped on the page match. os_aio_simulated_handle(): Call os_file_check_page_trailers() before and after os_file_write(). * row0mysql.c Move trx_commit_for_mysql(trx) calls before calls to row_mysql_unlock_data_dictionary(trx) (bug 19727). * row0sel.c row_fetch_print(): Handle SQL NULL values without crashing. row_sel_store_mysql_rec(): Remove useless call to rec_get_nth_field when handling an externally stored column. Fetch externally stored fields when using InnoDB's internal SQL parser. Optimize BLOB selects by using prebuilt->blob_heap directly instead of first reading BLOB data to a temporary heap and then copying it to prebuilt->blob_heap. * srv0srv.c srv_master_thread(): Remove unreachable code. * srv0start.c srv_parse_data_file_paths_and_sizes(): Accept lower-case 'm' and 'g' as abbreviations of megabyte and gigabyte (bug 19609). srv_parse_megabytes(): New fuction. * ut0dbg.c|h Implement InnoDB assertions (ut_a and ut_error) with abort() when the code is compiled with GCC 3 or later on other platforms than Windows or Netware. Also disable the variable ut_dbg_stop_threads and the function ut_dbg_stop_thread() i this case, unless UNIV_SYC_DEBUG is defined. This should allow the compiler to generate more compact code for assertions. * ut0list.c|h Add ib_list_create_heap().
478 lines
17 KiB
C
478 lines
17 KiB
C
/******************************************************
|
|
The read-write lock (for threads, not for database transactions)
|
|
|
|
(c) 1995 Innobase Oy
|
|
|
|
Created 9/11/1995 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#ifndef sync0rw_h
|
|
#define sync0rw_h
|
|
|
|
#include "univ.i"
|
|
#include "ut0lst.h"
|
|
#include "sync0sync.h"
|
|
#include "os0sync.h"
|
|
|
|
/* The following undef is to prevent a name conflict with a macro
|
|
in MySQL: */
|
|
#undef rw_lock_t
|
|
|
|
/* Latch types; these are used also in btr0btr.h: keep the numerical values
|
|
smaller than 30 and the order of the numerical values like below! */
|
|
#define RW_S_LATCH 1
|
|
#define RW_X_LATCH 2
|
|
#define RW_NO_LATCH 3
|
|
|
|
typedef struct rw_lock_struct rw_lock_t;
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
typedef struct rw_lock_debug_struct rw_lock_debug_t;
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
|
|
typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t;
|
|
|
|
extern rw_lock_list_t rw_lock_list;
|
|
extern mutex_t rw_lock_list_mutex;
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
/* The global mutex which protects debug info lists of all rw-locks.
|
|
To modify the debug info list of an rw-lock, this mutex has to be
|
|
|
|
acquired in addition to the mutex protecting the lock. */
|
|
extern mutex_t rw_lock_debug_mutex;
|
|
extern os_event_t rw_lock_debug_event; /* If deadlock detection does
|
|
not get immediately the mutex it
|
|
may wait for this event */
|
|
extern ibool rw_lock_debug_waiters; /* This is set to TRUE, if
|
|
there may be waiters for the event */
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
|
|
extern ulint rw_s_system_call_count;
|
|
extern ulint rw_s_spin_wait_count;
|
|
extern ulint rw_s_exit_count;
|
|
extern ulint rw_s_os_wait_count;
|
|
extern ulint rw_x_system_call_count;
|
|
extern ulint rw_x_spin_wait_count;
|
|
extern ulint rw_x_os_wait_count;
|
|
extern ulint rw_x_exit_count;
|
|
|
|
/**********************************************************************
|
|
Creates, or rather, initializes an rw-lock object in a specified memory
|
|
location (which must be appropriately aligned). The rw-lock is initialized
|
|
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
|
|
is necessary only if the memory block containing it is freed. */
|
|
#define rw_lock_create(L, level) rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
|
|
|
|
/*=====================*/
|
|
/**********************************************************************
|
|
Creates, or rather, initializes an rw-lock object in a specified memory
|
|
location (which must be appropriately aligned). The rw-lock is initialized
|
|
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
|
|
is necessary only if the memory block containing it is freed. */
|
|
|
|
void
|
|
rw_lock_create_func(
|
|
/*================*/
|
|
rw_lock_t* lock, /* in: pointer to memory */
|
|
ulint level, /* in: level */
|
|
const char* cfile_name, /* in: file name where created */
|
|
ulint cline, /* in: file line where created */
|
|
const char* cmutex_name); /* in: mutex name */
|
|
/**********************************************************************
|
|
Calling this function is obligatory only if the memory buffer containing
|
|
the rw-lock is freed. Removes an rw-lock object from the global list. The
|
|
rw-lock is checked to be in the non-locked state. */
|
|
|
|
void
|
|
rw_lock_free(
|
|
/*=========*/
|
|
rw_lock_t* lock); /* in: rw-lock */
|
|
/**********************************************************************
|
|
Checks that the rw-lock has been initialized and that there are no
|
|
simultaneous shared and exclusive locks. */
|
|
|
|
ibool
|
|
rw_lock_validate(
|
|
/*=============*/
|
|
rw_lock_t* lock);
|
|
/******************************************************************
|
|
NOTE! The following macros should be used in rw s-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_s_lock(M) rw_lock_s_lock_func(\
|
|
(M), 0, __FILE__, __LINE__)
|
|
/******************************************************************
|
|
NOTE! The following macros should be used in rw s-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_s_lock_gen(M, P) rw_lock_s_lock_func(\
|
|
(M), (P), __FILE__, __LINE__)
|
|
/******************************************************************
|
|
NOTE! The following macros should be used in rw s-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_s_lock_nowait(M) rw_lock_s_lock_func_nowait(\
|
|
(M), __FILE__, __LINE__)
|
|
/**********************************************************************
|
|
NOTE! Use the corresponding macro, not directly this function, except if
|
|
you supply the file name and line number. Lock an rw-lock in shared mode
|
|
for the current thread. If the rw-lock is locked in exclusive mode, or
|
|
there is an exclusive lock request waiting, the function spins a preset
|
|
time (controlled by SYNC_SPIN_ROUNDS), waiting for the lock, before
|
|
suspending the thread. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_s_lock_func(
|
|
/*================*/
|
|
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 */
|
|
/**********************************************************************
|
|
NOTE! Use the corresponding macro, not directly this function, except if
|
|
you supply the file name and line number. Lock an rw-lock in shared mode
|
|
for the current thread if the lock can be acquired immediately. */
|
|
UNIV_INLINE
|
|
ibool
|
|
rw_lock_s_lock_func_nowait(
|
|
/*=======================*/
|
|
/* out: TRUE if success */
|
|
rw_lock_t* lock, /* in: pointer to rw-lock */
|
|
const char* file_name,/* in: file name where lock requested */
|
|
ulint line); /* in: line where requested */
|
|
/**********************************************************************
|
|
NOTE! Use the corresponding macro, not directly this function! Lock an
|
|
rw-lock in exclusive mode for the current thread if the lock can be
|
|
obtained immediately. */
|
|
UNIV_INLINE
|
|
ibool
|
|
rw_lock_x_lock_func_nowait(
|
|
/*=======================*/
|
|
/* out: TRUE if success */
|
|
rw_lock_t* lock, /* in: pointer to rw-lock */
|
|
const char* file_name,/* in: file name where lock requested */
|
|
ulint line); /* in: line where requested */
|
|
/**********************************************************************
|
|
Releases a shared mode lock. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_s_unlock_func(
|
|
/*==================*/
|
|
rw_lock_t* lock /* in: rw-lock */
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
,ulint pass /* in: pass value; != 0, if the lock may have
|
|
been passed to another thread to unlock */
|
|
#endif
|
|
);
|
|
/***********************************************************************
|
|
Releases a shared mode lock. */
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L, 0)
|
|
#else
|
|
#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L)
|
|
#endif
|
|
/***********************************************************************
|
|
Releases a shared mode lock. */
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L, P)
|
|
#else
|
|
#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
|
|
#endif
|
|
/******************************************************************
|
|
NOTE! The following macro should be used in rw x-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_x_lock(M) rw_lock_x_lock_func(\
|
|
(M), 0, __FILE__, __LINE__)
|
|
/******************************************************************
|
|
NOTE! The following macro should be used in rw x-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_x_lock_gen(M, P) rw_lock_x_lock_func(\
|
|
(M), (P), __FILE__, __LINE__)
|
|
/******************************************************************
|
|
NOTE! The following macros should be used in rw x-locking, not the
|
|
corresponding function. */
|
|
|
|
#define rw_lock_x_lock_nowait(M) rw_lock_x_lock_func_nowait(\
|
|
(M), __FILE__, __LINE__)
|
|
/**********************************************************************
|
|
NOTE! Use the corresponding macro, not directly this function! Lock an
|
|
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
|
|
in shared or exclusive mode, or there is an exclusive lock request waiting,
|
|
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
|
|
for the lock, before suspending the thread. If the same thread has an x-lock
|
|
on the rw-lock, locking succeed, with the following exception: if pass != 0,
|
|
only a single x-lock may be taken on the lock. NOTE: If the same thread has
|
|
an s-lock, locking does not succeed! */
|
|
|
|
void
|
|
rw_lock_x_lock_func(
|
|
/*================*/
|
|
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 */
|
|
/**********************************************************************
|
|
Releases an exclusive mode lock. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_x_unlock_func(
|
|
/*==================*/
|
|
rw_lock_t* lock /* in: rw-lock */
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
,ulint pass /* in: pass value; != 0, if the lock may have
|
|
been passed to another thread to unlock */
|
|
#endif
|
|
);
|
|
/***********************************************************************
|
|
Releases an exclusive mode lock. */
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L, 0)
|
|
#else
|
|
#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L)
|
|
#endif
|
|
/***********************************************************************
|
|
Releases an exclusive mode lock. */
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L, P)
|
|
#else
|
|
#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
|
|
#endif
|
|
/**********************************************************************
|
|
Low-level function which locks an rw-lock in s-mode when we know that it
|
|
is possible and none else is currently accessing the rw-lock structure.
|
|
Then we can do the locking without reserving the mutex. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_s_lock_direct(
|
|
/*==================*/
|
|
rw_lock_t* lock, /* in: pointer to rw-lock */
|
|
const char* file_name, /* in: file name where requested */
|
|
ulint line /* in: line where lock requested */
|
|
);
|
|
/**********************************************************************
|
|
Low-level function which locks an rw-lock in x-mode when we know that it
|
|
is not locked and none else is currently accessing the rw-lock structure.
|
|
Then we can do the locking without reserving the mutex. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_x_lock_direct(
|
|
/*==================*/
|
|
rw_lock_t* lock, /* in: pointer to rw-lock */
|
|
const char* file_name, /* in: file name where requested */
|
|
ulint line /* in: line where lock requested */
|
|
);
|
|
/**********************************************************************
|
|
This function is used in the insert buffer to move the ownership of an
|
|
x-latch on a buffer frame to the current thread. The x-latch was set by
|
|
the buffer read operation and it protected the buffer frame while the
|
|
read was done. The ownership is moved because we want that the current
|
|
thread is able to acquire a second x-latch which is stored in an mtr.
|
|
This, in turn, is needed to pass the debug checks of index page
|
|
operations. */
|
|
|
|
void
|
|
rw_lock_x_lock_move_ownership(
|
|
/*==========================*/
|
|
rw_lock_t* lock); /* in: lock which was x-locked in the
|
|
buffer read */
|
|
/**********************************************************************
|
|
Releases a shared mode lock when we know there are no waiters and none
|
|
else will access the lock during the time this function is executed. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_s_unlock_direct(
|
|
/*====================*/
|
|
rw_lock_t* lock); /* in: rw-lock */
|
|
/**********************************************************************
|
|
Releases an exclusive mode lock when we know there are no waiters, and
|
|
none else will access the lock durint the time this function is executed. */
|
|
UNIV_INLINE
|
|
void
|
|
rw_lock_x_unlock_direct(
|
|
/*====================*/
|
|
rw_lock_t* lock); /* in: rw-lock */
|
|
/**********************************************************************
|
|
Returns the value of writer_count for the lock. Does not reserve the lock
|
|
mutex, so the caller must be sure it is not changed during the call. */
|
|
UNIV_INLINE
|
|
ulint
|
|
rw_lock_get_x_lock_count(
|
|
/*=====================*/
|
|
/* out: value of writer_count */
|
|
rw_lock_t* lock); /* in: rw-lock */
|
|
/************************************************************************
|
|
Accessor functions for rw lock. */
|
|
UNIV_INLINE
|
|
ulint
|
|
rw_lock_get_waiters(
|
|
/*================*/
|
|
rw_lock_t* lock);
|
|
UNIV_INLINE
|
|
ulint
|
|
rw_lock_get_writer(
|
|
/*===============*/
|
|
rw_lock_t* lock);
|
|
UNIV_INLINE
|
|
ulint
|
|
rw_lock_get_reader_count(
|
|
/*=====================*/
|
|
rw_lock_t* lock);
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
/**********************************************************************
|
|
Checks if the thread has locked the rw-lock in the specified mode, with
|
|
the pass value == 0. */
|
|
|
|
ibool
|
|
rw_lock_own(
|
|
/*========*/
|
|
rw_lock_t* lock, /* in: rw-lock */
|
|
ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
|
|
RW_LOCK_EX */
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
/**********************************************************************
|
|
Checks if somebody has locked the rw-lock in the specified mode. */
|
|
|
|
ibool
|
|
rw_lock_is_locked(
|
|
/*==============*/
|
|
rw_lock_t* lock, /* in: rw-lock */
|
|
ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
|
|
RW_LOCK_EX */
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
/*******************************************************************
|
|
Prints debug info of an rw-lock. */
|
|
|
|
void
|
|
rw_lock_print(
|
|
/*==========*/
|
|
rw_lock_t* lock); /* in: rw-lock */
|
|
/*******************************************************************
|
|
Prints debug info of currently locked rw-locks. */
|
|
|
|
void
|
|
rw_lock_list_print_info(void);
|
|
/*=========================*/
|
|
/*******************************************************************
|
|
Returns the number of currently locked rw-locks.
|
|
Works only in the debug version. */
|
|
|
|
ulint
|
|
rw_lock_n_locked(void);
|
|
/*==================*/
|
|
|
|
/*#####################################################################*/
|
|
|
|
/**********************************************************************
|
|
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
|
|
because the debug mutex is also acquired in sync0arr while holding the OS
|
|
mutex protecting the sync array, and the ordinary mutex_enter might
|
|
recursively call routines in sync0arr, leading to a deadlock on the OS
|
|
mutex. */
|
|
|
|
void
|
|
rw_lock_debug_mutex_enter(void);
|
|
/*==========================*/
|
|
/**********************************************************************
|
|
Releases the debug mutex. */
|
|
|
|
void
|
|
rw_lock_debug_mutex_exit(void);
|
|
/*==========================*/
|
|
/*************************************************************************
|
|
Prints info of a debug struct. */
|
|
|
|
void
|
|
rw_lock_debug_print(
|
|
/*================*/
|
|
rw_lock_debug_t* info); /* in: debug struct */
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
|
|
/* NOTE! The structure appears here only for the compiler to know its size.
|
|
Do not use its fields directly! The structure used in the spin lock
|
|
implementation of a read-write lock. Several threads may have a shared lock
|
|
simultaneously in this lock, but only one writer may have an exclusive lock,
|
|
in which case no shared locks are allowed. To prevent starving of a writer
|
|
blocked by readers, a writer may queue for the lock by setting the writer
|
|
field. Then no new readers are allowed in. */
|
|
|
|
struct rw_lock_struct {
|
|
ulint reader_count; /* Number of readers who have locked this
|
|
lock in the shared mode */
|
|
ulint writer; /* This field is set to RW_LOCK_EX if there
|
|
is a writer owning the lock (in exclusive
|
|
mode), RW_LOCK_WAIT_EX if a writer is
|
|
queueing for the lock, and
|
|
RW_LOCK_NOT_LOCKED, otherwise. */
|
|
os_thread_id_t writer_thread;
|
|
/* Thread id of a possible writer thread */
|
|
ulint writer_count; /* Number of times the same thread has
|
|
recursively locked the lock in the exclusive
|
|
mode */
|
|
mutex_t mutex; /* The mutex protecting rw_lock_struct */
|
|
ulint pass; /* Default value 0. This is set to some
|
|
value != 0 given by the caller of an x-lock
|
|
operation, if the x-lock is to be passed to
|
|
another thread to unlock (which happens in
|
|
asynchronous i/o). */
|
|
ulint waiters; /* This ulint is set to 1 if there are
|
|
waiters (readers or writers) in the global
|
|
wait array, waiting for this rw_lock.
|
|
Otherwise, == 0. */
|
|
ibool writer_is_wait_ex;
|
|
/* This is TRUE if the writer field is
|
|
RW_LOCK_WAIT_EX; this field is located far
|
|
from the memory update hotspot fields which
|
|
are at the start of this struct, thus we can
|
|
peek this field without causing much memory
|
|
bus traffic */
|
|
UT_LIST_NODE_T(rw_lock_t) list;
|
|
/* All allocated rw locks are put into a
|
|
list */
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
|
|
/* In the debug version: pointer to the debug
|
|
info list of the lock */
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
|
|
ulint level; /* Level in the global latching order. */
|
|
const char* cfile_name;/* File name where lock created */
|
|
ulint cline; /* Line where created */
|
|
const char* last_s_file_name;/* File name where last s-locked */
|
|
const char* last_x_file_name;/* File name where last x-locked */
|
|
ulint last_s_line; /* Line number where last time s-locked */
|
|
ulint last_x_line; /* Line number where last time x-locked */
|
|
ulint magic_n;
|
|
};
|
|
|
|
#define RW_LOCK_MAGIC_N 22643
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
/* The structure for storing debug info of an rw-lock */
|
|
struct rw_lock_debug_struct {
|
|
|
|
os_thread_id_t thread_id; /* The thread id of the thread which
|
|
locked the rw-lock */
|
|
ulint pass; /* Pass value given in the lock operation */
|
|
ulint lock_type; /* Type of the lock: RW_LOCK_EX,
|
|
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
|
|
const char* file_name;/* File name where the lock was obtained */
|
|
ulint line; /* Line where the rw-lock was locked */
|
|
UT_LIST_NODE_T(rw_lock_debug_t) list;
|
|
/* Debug structs are linked in a two-way
|
|
list */
|
|
};
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
|
|
#ifndef UNIV_NONINL
|
|
#include "sync0rw.ic"
|
|
#endif
|
|
|
|
#endif
|