Commit 5a6d4e7e authored by lenz@mysql.com's avatar lenz@mysql.com

Merge lgrimmer@build.mysql.com:/home/bk/mysql-4.0

into mysql.com:/space/my/mysql-4.0
parents 048b89f0 41a5f79a
......@@ -103,7 +103,8 @@ struct com_shm_endpoint_struct{
the area currently may contain a datagram;
NOTE: automatic event */
os_event_t empty; /* this is in the signaled state if the area
currently may be empty; NOTE: automatic event */
currently may be empty; NOTE: automatic
event */
ip_mutex_hdl_t* ip_mutex; /* handle to the interprocess mutex
protecting the shared memory */
UT_LIST_NODE_T(com_shm_endpoint_t) list; /* If the endpoint struct
......@@ -793,16 +794,18 @@ com_shm_create_or_open(
ut_strcpy(buf + len, (char*)"_IBSHM_EV_NE"),
event_ne = os_event_create_auto(buf);
event_ne = os_event_create(buf);
ut_ad(event_ne);
ut_strcpy(buf + len, (char*)"_IBSHM_EV_EM"),
event_em = os_event_create_auto(buf);
event_em = os_event_create(buf);
ut_ad(event_em);
ut_a(0); /* event_ne and event_em should be auto events! */
com_shm_endpoint_set_shm(ep, shm);
com_shm_endpoint_set_map(ep, map);
......
......@@ -13,13 +13,26 @@ Created 9/6/1995 Heikki Tuuri
#include "ut0lst.h"
#ifdef __WIN__
#define os_fast_mutex_t CRITICAL_SECTION
typedef HANDLE os_event_t;
typedef HANDLE os_native_event_t;
typedef struct os_event_struct os_event_struct_t;
typedef os_event_struct_t* os_event_t;
struct os_event_struct {
os_native_event_t handle;
/* Windows event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
/* list of all created events */
};
#else
typedef pthread_mutex_t os_fast_mutex_t;
typedef struct os_event_struct os_event_struct_t;
typedef os_event_struct_t* os_event_t;
struct os_event_struct {
os_fast_mutex_t os_mutex; /* this mutex protects the next
fields */
......@@ -39,16 +52,16 @@ typedef os_mutex_str_t* os_mutex_t;
#define OS_SYNC_TIME_EXCEEDED 1
/* Mutex protecting the thread count and event and OS 'slow' mutex lists */
/* Mutex protecting counts and the event and OS 'slow' mutex lists */
extern os_mutex_t os_sync_mutex;
/* This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
extern ulint os_thread_count;
/* The following are approximate counters for debugging in Unix */
extern ulint os_event_count;
extern ulint os_mutex_count;
extern ulint os_fast_mutex_count;
/*************************************************************
Initializes global event and OS 'slow' mutex lists. */
......@@ -57,15 +70,14 @@ void
os_sync_init(void);
/*==============*/
/*************************************************************
Frees created events (not in Windows) and OS 'slow' mutexes. */
Frees created events and OS 'slow' mutexes. */
void
os_sync_free(void);
/*==============*/
/*************************************************************
Creates an event semaphore, i.e., a semaphore which may
just have two states: signaled and nonsignaled.
The created event is manual reset: it must be reset
/*************************************************************
Creates an event semaphore, i.e., a semaphore which may just have two states:
signaled and nonsignaled. The created event is manual reset: it must be reset
explicitly by calling sync_os_reset_event. */
os_event_t
......@@ -74,10 +86,10 @@ os_event_create(
/* out: the event handle */
char* name); /* in: the name of the event, if NULL
the event is created without a name */
#ifdef __WIN__
/*************************************************************
Creates an auto-reset event semaphore, i.e., an event
which is automatically reset when a single thread is
released. */
Creates an auto-reset event semaphore, i.e., an event which is automatically
reset when a single thread is released. Works only in Windows. */
os_event_t
os_event_create_auto(
......@@ -85,6 +97,7 @@ os_event_create_auto(
/* out: the event handle */
char* name); /* in: the name of the event, if NULL
the event is created without a name */
#endif
/**************************************************************
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
......@@ -120,7 +133,7 @@ os_event_wait(
os_event_t event); /* in: event to wait */
/**************************************************************
Waits for an event object until it is in the signaled state or
a timeout is exceeded. */
a timeout is exceeded. In Unix the timeout is always infinite. */
ulint
os_event_wait_time(
......@@ -131,8 +144,9 @@ os_event_wait_time(
os_event_t event, /* in: event to wait */
ulint time); /* in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
#ifdef __WIN__
/**************************************************************
Waits for any event in an event array. Returns if even a single
Waits for any event in an OS native event array. Returns if even a single
one is signaled or becomes signaled. */
ulint
......@@ -140,14 +154,15 @@ os_event_wait_multiple(
/*===================*/
/* out: index of the event
which was signaled */
ulint n, /* in: number of events in the
ulint n, /* in: number of events in the
array */
os_event_t* event_array); /* in: pointer to an array of event
os_native_event_t* native_event_array);
/* in: pointer to an array of event
handles */
#endif
/*************************************************************
Creates an operating system mutex semaphore.
Because these are slow, the mutex semaphore of the database
itself (sync_mutex_t) should be used where possible. */
Creates an operating system mutex semaphore. Because these are slow, the
mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
os_mutex_t
os_mutex_create(
......
......@@ -44,4 +44,3 @@ os_fast_mutex_trylock(
#endif
#endif
}
......@@ -65,7 +65,9 @@ os_thread_pf(
/********************************************************************
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
and returns a ulint. */
and returns a ulint.
NOTE: We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_t
os_thread_create(
......
......@@ -80,6 +80,8 @@ struct os_aio_slot_struct{
which pending aio operation was
completed */
#ifdef WIN_ASYNC_IO
os_event_t event; /* event object we need in the
OVERLAPPED struct */
OVERLAPPED control; /* Windows control block for the
aio request */
#elif defined(POSIX_ASYNC_IO)
......@@ -107,11 +109,14 @@ struct os_aio_array_struct{
ulint n_reserved;/* Number of reserved slots in the
aio array outside the ibuf segment */
os_aio_slot_t* slots; /* Pointer to the slots in the array */
os_event_t* events; /* Pointer to an array of event handles
where we copied the handles from slots,
in the same order. This can be used in
WaitForMultipleObjects; used only in
#ifdef __WIN__
os_native_event_t* native_events;
/* Pointer to an array of OS native event
handles where we copied the handles from
slots, in the same order. This can be used
in WaitForMultipleObjects; used only in
Windows */
#endif
};
/* Array of events used in simulated aio */
......@@ -296,7 +301,7 @@ os_file_handle_error(
operation */
os_file_t file, /* in: file pointer */
char* name, /* in: name of a file or NULL */
const char* operation) /* in: type of operation */
const char* operation)/* in: operation */
{
ulint err;
......@@ -338,8 +343,8 @@ os_file_handle_error(
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
}
fprintf(stderr, "InnoDB: system call %s\n", operation);
fprintf(stderr, "InnoDB: System call %s.\n", operation);
fprintf(stderr, "InnoDB: Cannot continue operation.\n");
fflush(stderr);
......@@ -422,9 +427,8 @@ try_again:
*success = FALSE;
retry = os_file_handle_error(file, name,
create_mode == OS_FILE_OPEN ?
"open" : "create");
create_mode == OS_FILE_OPEN ?
"open" : "create");
if (retry) {
goto try_again;
}
......@@ -465,10 +469,8 @@ try_again:
*success = FALSE;
retry = os_file_handle_error(file, name,
create_mode == OS_FILE_OPEN ?
"open" : "create");
create_mode == OS_FILE_OPEN ?
"open" : "create");
if (retry) {
goto try_again;
}
......@@ -576,9 +578,8 @@ try_again:
*success = FALSE;
retry = os_file_handle_error(file, name,
create_mode == OS_FILE_OPEN ?
"open" : "create");
create_mode == OS_FILE_OPEN ?
"open" : "create");
if (retry) {
goto try_again;
}
......@@ -625,9 +626,8 @@ try_again:
*success = FALSE;
retry = os_file_handle_error(file, name,
create_mode == OS_FILE_OPEN ?
"open" : "create");
create_mode == OS_FILE_OPEN ?
"open" : "create");
if (retry) {
goto try_again;
}
......@@ -1319,19 +1319,22 @@ os_aio_array_create(
array->n_segments = n_segments;
array->n_reserved = 0;
array->slots = ut_malloc(n * sizeof(os_aio_slot_t));
array->events = ut_malloc(n * sizeof(os_event_t));
#ifdef __WIN__
array->native_events = ut_malloc(n * sizeof(os_native_event_t));
#endif
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i);
slot->pos = i;
slot->reserved = FALSE;
#ifdef WIN_ASYNC_IO
slot->event = os_event_create(NULL);
over = &(slot->control);
over->hEvent = os_event_create(NULL);
over->hEvent = slot->event->handle;
*((array->events) + i) = over->hEvent;
*((array->native_events) + i) = over->hEvent;
#endif
}
......@@ -1429,7 +1432,7 @@ os_aio_array_wake_win_aio_at_shutdown(
for (i = 0; i < array->n_slots; i++) {
os_event_set(*(array->events + i));
os_event_set((array->slots + i)->event);
}
}
#endif
......@@ -1689,7 +1692,7 @@ loop:
control = &(slot->control);
control->Offset = (DWORD)offset;
control->OffsetHigh = (DWORD)offset_high;
os_event_reset(control->hEvent);
os_event_reset(slot->event);
#elif defined(POSIX_ASYNC_IO)
......@@ -1747,7 +1750,7 @@ os_aio_array_free_slot(
}
#ifdef WIN_ASYNC_IO
os_event_reset(slot->control.hEvent);
os_event_reset(slot->event);
#endif
os_mutex_exit(array->mutex);
}
......@@ -1872,7 +1875,7 @@ os_aio(
offset where to read or write */
ulint offset_high, /* in: most significant 32 bits of
offset */
ulint n, /* in: number of bytes to read or write */
ulint n, /* in: number of bytes to read or write */
void* message1,/* in: messages for the aio handler (these
can be used to identify a completed aio
operation); if mode is OS_AIO_SYNC, these
......@@ -1916,7 +1919,8 @@ os_aio(
wait in the Windows case. */
if (type == OS_FILE_READ) {
return(os_file_read(file, buf, offset, offset_high, n));
return(os_file_read(file, buf, offset,
offset_high, n));
}
ut_a(type == OS_FILE_WRITE);
......@@ -1994,8 +1998,7 @@ try_again:
#ifdef WIN_ASYNC_IO
if (os_aio_use_native_aio) {
if ((ret && len == n)
|| (!ret && GetLastError() == ERROR_IO_PENDING)) {
|| (!ret && GetLastError() == ERROR_IO_PENDING)) {
/* aio was queued successfully! */
if (mode == OS_AIO_SYNC) {
......@@ -2025,8 +2028,8 @@ try_again:
os_aio_array_free_slot(array, slot);
retry = os_file_handle_error(file, name, "aio");
retry = os_file_handle_error(file, name,
type == OS_FILE_READ ? "aio read" : "aio write");
if (retry) {
goto try_again;
......@@ -2091,15 +2094,15 @@ os_aio_windows_handle(
n = array->n_slots / array->n_segments;
if (array == os_aio_sync_array) {
srv_io_thread_op_info[orig_seg] = "wait Windows aio for 1 page";
ut_ad(pos < array->n_slots);
os_event_wait(array->events[pos]);
srv_io_thread_op_info[orig_seg] =
"wait Windows aio for 1 page";
os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
i = pos;
} else {
srv_io_thread_op_info[orig_seg] =
"wait Windows aio";
i = os_event_wait_multiple(n, (array->events) + segment * n);
i = os_event_wait_multiple(n,
(array->native_events) + segment * n);
}
os_mutex_enter(array->mutex);
......@@ -2124,7 +2127,7 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
} else {
os_file_handle_error(slot->file, slot->name, "aio");
os_file_handle_error(slot->file, slot->name, "Windows aio");
ret_val = FALSE;
}
......
This diff is collapsed.
......@@ -186,6 +186,10 @@ os_thread_exit(
void* exit_value) /* in: exit value; in Windows this void*
is cast as a DWORD */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
printf("A thread exits.\n");
printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id()));
#endif
os_mutex_enter(os_sync_mutex);
os_thread_count--;
os_mutex_exit(os_sync_mutex);
......
......@@ -856,6 +856,7 @@ srv_release_max_if_no_queries(void)
mutex_exit(&kernel_mutex);
}
#ifdef notdefined
/***********************************************************************
Releases one utility thread if no queries are active and
the high-water mark 2 for the utility is exceeded. */
......@@ -890,7 +891,6 @@ srv_release_one_if_no_queries(void)
mutex_exit(&kernel_mutex);
}
#ifdef notdefined
/***********************************************************************
Decrements the utility meter by the value given and suspends the calling
thread, which must be an utility thread of the type given, if necessary. */
......@@ -1000,6 +1000,8 @@ srv_communication_init(
ut_a(ret == 0);
}
#ifdef notdefined
/*************************************************************************
Implements the recovery utility. */
......@@ -1060,6 +1062,7 @@ srv_purge_thread(
return(0);
}
#endif /* notdefined */
/*************************************************************************
Creates the utility threads. */
......@@ -1090,6 +1093,7 @@ srv_create_utility_threads(void)
ut_a(thread); */
}
#ifdef notdefined
/*************************************************************************
Implements the communication threads. */
static
......@@ -1139,6 +1143,7 @@ srv_com_thread(
return(0);
}
#endif
/*************************************************************************
Creates the communication threads. */
......@@ -1159,6 +1164,7 @@ srv_create_com_threads(void)
}
}
#ifdef notdefined
/*************************************************************************
Implements the worker threads. */
static
......@@ -1203,6 +1209,7 @@ srv_worker_thread(
return(0);
}
#endif
/*************************************************************************
Creates the worker threads. */
......@@ -2456,6 +2463,10 @@ srv_lock_timeout_and_monitor_thread(
char* buf;
ulint i;
#ifdef UNIV_DEBUG_THREAD_CREATION
printf("Lock timeout thread starts\n");
printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id()));
#endif
UT_NOT_USED(arg);
srv_last_monitor_time = time(NULL);
last_table_monitor_time = time(NULL);
......@@ -2596,6 +2607,10 @@ loop:
exit_func:
srv_lock_timeout_and_monitor_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
#ifndef __WIN__
return(NULL);
#else
......@@ -2621,6 +2636,10 @@ srv_error_monitor_thread(
ulint cnt = 0;
UT_NOT_USED(arg);
#ifdef UNIV_DEBUG_THREAD_CREATION
printf("Error monitor thread starts\n");
printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id()));
#endif
loop:
srv_error_monitor_active = TRUE;
......@@ -2657,6 +2676,9 @@ loop:
srv_error_monitor_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
#ifndef __WIN__
......@@ -2737,6 +2759,10 @@ srv_master_thread(
UT_NOT_USED(arg);
#ifdef UNIV_DEBUG_THREAD_CREATION
printf("Master thread starts\n");
printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id()));
#endif
srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
......@@ -2972,6 +2998,15 @@ background_loop:
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
if (n_tables_to_drop > 0) {
/* Do not monopolize the CPU even if there are tables waiting
in the background drop queue. (It is essentially a bug if
MySQL tries to drop a table while there are still open handles
to it and we had to put it to the background drop queue.) */
os_thread_sleep(100000);
}
srv_main_thread_op_info = (char*)"purging";
if (srv_fast_shutdown && srv_shutdown_state > 0) {
......@@ -3110,6 +3145,13 @@ suspend_thread:
goto loop;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit.
The thread actually never comes here because it is exited in an
os_event_wait(). */
os_thread_exit(NULL);
#ifndef __WIN__
return(NULL);
#else
......
......@@ -414,8 +414,10 @@ io_handler_thread(
segment = *((ulint*)arg);
/* printf("Io handler thread %lu starts\n", segment); */
#ifdef UNIV_DEBUG_THREAD_CREATION
printf("Io handler thread %lu starts\n", segment);
printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id()));
#endif
for (i = 0;; i++) {
fil_aio_wait(segment);
......@@ -424,6 +426,13 @@ io_handler_thread(
mutex_exit(&ios_mutex);
}
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit.
The thread actually never comes here because it is exited in an
os_event_wait(). */
os_thread_exit(NULL);
#ifndef __WIN__
return(NULL);
#else
......@@ -1546,21 +1555,32 @@ innobase_shutdown_for_mysql(void)
os_thread_count);
}
/* 3. Free all InnoDB's own mutexes */
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
them */
sync_close();
/* 4. Free all OS synchronization primitives (in Windows currently
events are not freed) */
/* 4. Free the os_conc_mutex and all os_events and os_mutexes */
srv_free();
os_sync_free();
/* 5. Free all allocated memory (and the os_fast_mutex created in
/* 5. Free all allocated memory and the os_fast_mutex created in
ut0mem.c */
ut_free_all_mem();
if (os_thread_count != 0
|| os_event_count != 0
|| os_mutex_count != 0
|| os_fast_mutex_count != 0) {
fprintf(stderr,
"InnoDB: Warning: some resources were not cleaned up in shutdown:\n"
"InnoDB: threads %lu, events %lu, os_mutexes %lu, os_fast_mutexes %lu\n",
os_thread_count, os_event_count, os_mutex_count,
os_fast_mutex_count);
}
if (srv_print_verbose_log) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Shutdown completed\n");
......
......@@ -2081,8 +2081,13 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
else
{
sql_print_error("\
Could not parse log event entry, check the master for binlog corruption\n\
This may also be a network problem, or just a bug in the master or slave code.\
Could not parse relay log event entry. The possible reasons are: the master's \
binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
binary log), the slave's relay log is corrupted (you can check this by running \
'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
or slave's MySQL code. If you want to check the master's binary log or slave's \
relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
on this slave.\
");
return 1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment