mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
2662b59306
Docs/manual.texi: Added Innobase documentation configure.in: Incremented version include/my_base.h: Added option for Innobase myisam/mi_check.c: cleanup mysql-test/t/bdb.test: cleanup mysql-test/t/innobase.test: Extended with new tests from bdb.test mysql-test/t/merge.test: Added test of SHOW create mysys/my_init.c: Fix for UNIXWARE 7 scripts/mysql_install_db.sh: Always write how to start mysqld scripts/safe_mysqld.sh: Fixed type sql/ha_innobase.cc: Update to new version sql/ha_innobase.h: Update to new version sql/handler.h: Added 'update_table_comment()' and 'append_create_info()' sql/sql_delete.cc: Fixes for Innobase sql/sql_select.cc: Fixes for Innobase sql/sql_show.cc: Append create information (for MERGE tables) sql/sql_update.cc: Fixes for Innobase
182 lines
3.6 KiB
Text
182 lines
3.6 KiB
Text
/******************************************************
|
|
A fast mutex for interprocess synchronization.
|
|
mutex_t can be used only within single process,
|
|
but ip_mutex_t also between processes.
|
|
|
|
(c) 1995 Innobase Oy
|
|
|
|
Created 9/30/1995 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
/* An extra structure created in the private address space of each process
|
|
which creates or opens the ip mutex. */
|
|
|
|
struct ip_mutex_hdl_struct {
|
|
ip_mutex_t* ip_mutex; /* pointer to ip mutex */
|
|
os_event_t released; /* event which signals that the mutex
|
|
is released; this is obtained from
|
|
create or open of an ip mutex */
|
|
os_mutex_t exclude; /* os mutex obtained when ip mutex is
|
|
created or opened */
|
|
};
|
|
|
|
|
|
UNIV_INLINE
|
|
ulint
|
|
ip_mutex_get_waiters(
|
|
volatile ip_mutex_t* ipm);
|
|
UNIV_INLINE
|
|
void
|
|
ip_mutex_set_waiters(
|
|
volatile ip_mutex_t* ipm,
|
|
ulint flag);
|
|
UNIV_INLINE
|
|
mutex_t*
|
|
ip_mutex_get_mutex(
|
|
ip_mutex_t* ipm);
|
|
|
|
|
|
/******************************************************************
|
|
Accessor functions for ip mutex. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ip_mutex_get_waiters(
|
|
volatile ip_mutex_t* ipm)
|
|
{
|
|
return(ipm->waiters);
|
|
}
|
|
UNIV_INLINE
|
|
void
|
|
ip_mutex_set_waiters(
|
|
volatile ip_mutex_t* ipm,
|
|
ulint flag)
|
|
{
|
|
ipm->waiters = flag;
|
|
}
|
|
UNIV_INLINE
|
|
mutex_t*
|
|
ip_mutex_get_mutex(
|
|
ip_mutex_t* ipm)
|
|
{
|
|
return(&(ipm->mutex));
|
|
}
|
|
|
|
/******************************************************************
|
|
Reserves an ip mutex. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ip_mutex_enter(
|
|
/*===========*/
|
|
/* out: 0 if success,
|
|
SYNC_TIME_EXCEEDED if timeout */
|
|
ip_mutex_hdl_t* ip_mutex_hdl, /* in: pointer to ip mutex handle */
|
|
ulint time) /* in: maximum time to wait, in
|
|
microseconds, or
|
|
SYNC_INFINITE_TIME */
|
|
{
|
|
mutex_t* mutex;
|
|
os_event_t released;
|
|
os_mutex_t exclude;
|
|
ip_mutex_t* ip_mutex;
|
|
ulint loop_count;
|
|
ulint ret;
|
|
|
|
ip_mutex = ip_mutex_hdl->ip_mutex;
|
|
released = ip_mutex_hdl->released;
|
|
exclude = ip_mutex_hdl->exclude;
|
|
|
|
mutex = ip_mutex_get_mutex(ip_mutex);
|
|
|
|
loop_count = 0;
|
|
loop:
|
|
loop_count++;
|
|
ut_ad(loop_count < 15);
|
|
|
|
if (mutex_enter_nowait(mutex) == 0) {
|
|
/* Succeeded! */
|
|
|
|
return(0);
|
|
}
|
|
|
|
ip_mutex_system_call_count++;
|
|
|
|
os_event_reset(released);
|
|
|
|
/* Order is important here: FIRST reset event, then set waiters */
|
|
ip_mutex_set_waiters(ip_mutex, 1);
|
|
|
|
if (mutex_enter_nowait(mutex) == 0) {
|
|
/* Succeeded! */
|
|
|
|
return(0);
|
|
}
|
|
|
|
if (time == SYNC_INFINITE_TIME) {
|
|
time = OS_SYNC_INFINITE_TIME;
|
|
}
|
|
|
|
/* Suspend to wait for release */
|
|
|
|
ip_mutex_system_call_count++;
|
|
|
|
ret = os_event_wait_time(released, time);
|
|
|
|
ip_mutex_system_call_count++;
|
|
|
|
os_mutex_enter(exclude);
|
|
ip_mutex_system_call_count++;
|
|
os_mutex_exit(exclude);
|
|
|
|
if (ret != 0) {
|
|
ut_a(ret == OS_SYNC_TIME_EXCEEDED);
|
|
|
|
return(SYNC_TIME_EXCEEDED);
|
|
}
|
|
|
|
goto loop;
|
|
}
|
|
|
|
/******************************************************************
|
|
Releases an ip mutex. */
|
|
UNIV_INLINE
|
|
void
|
|
ip_mutex_exit(
|
|
/*==========*/
|
|
ip_mutex_hdl_t* ip_mutex_hdl) /* in: pointer to ip mutex handle */
|
|
{
|
|
mutex_t* mutex;
|
|
os_event_t released;
|
|
os_mutex_t exclude;
|
|
ip_mutex_t* ip_mutex;
|
|
|
|
ip_mutex = ip_mutex_hdl->ip_mutex;
|
|
released = ip_mutex_hdl->released;
|
|
exclude = ip_mutex_hdl->exclude;
|
|
|
|
mutex = ip_mutex_get_mutex(ip_mutex);
|
|
|
|
mutex_exit(mutex);
|
|
|
|
if (ip_mutex_get_waiters(ip_mutex) != 0) {
|
|
|
|
ip_mutex_set_waiters(ip_mutex, 0);
|
|
|
|
/* Order is important here: FIRST reset waiters,
|
|
then set event */
|
|
|
|
ip_mutex_system_call_count++;
|
|
os_mutex_enter(exclude);
|
|
|
|
/* The use of the exclude mutex seems to prevent some
|
|
kind of a convoy problem in the test tsproc.c. We do
|
|
not know why. */
|
|
|
|
ip_mutex_system_call_count++;
|
|
|
|
os_event_set(released);
|
|
|
|
ip_mutex_system_call_count++;
|
|
|
|
os_mutex_exit(exclude);
|
|
}
|
|
}
|