MDEV-531 : Warning: Forcing close of thread ... in rpl_binlog_index

Use post_kill_notification in for one_thread_per_connection scheduler, 
the same as already used in threadpool, to reliably wake a thread  stuck in 
read() or in different poll() variations.
This commit is contained in:
Vladislav Vaintroub 2012-11-02 10:43:52 +01:00
parent 27bcea09e5
commit 4ffc9c3b01
7 changed files with 33 additions and 36 deletions

View File

@ -177,6 +177,12 @@ void vio_end(void);
#endif /* !defined(DONT_MAP_VIO) */ #endif /* !defined(DONT_MAP_VIO) */
#ifdef _WIN32 #ifdef _WIN32
/* shutdown(2) flags */
#ifndef SHUT_RD
#define SHUT_RD SD_BOTH
#endif
/* /*
Set thread id for io cancellation (required on Windows XP only, Set thread id for io cancellation (required on Windows XP only,
and should to be removed if XP is no more supported) and should to be removed if XP is no more supported)

View File

@ -97,7 +97,6 @@ INSERT INTO global_suppressions VALUES
("Failed to open log"), ("Failed to open log"),
("Failed to open the existing master info file"), ("Failed to open the existing master info file"),
("Forcing shutdown of [0-9]* plugins"), ("Forcing shutdown of [0-9]* plugins"),
("Forcing close of thread"),
/* /*
Due to timing issues, it might be that this warning Due to timing issues, it might be that this warning

View File

@ -79,11 +79,34 @@ void scheduler_init() {
scheduler_wait_sync_end); scheduler_wait_sync_end);
} }
/**
Kill notification callback, used by one-thread-per-connection
and threadpool scheduler.
Wakes up a thread that is stuck in read/poll/epoll/event-poll
routines used by threadpool, such that subsequent attempt to
read from client connection will result in IO error.
*/
void post_kill_notification(THD *thd)
{
DBUG_ENTER("post_kill_notification");
if (current_thd == thd || thd->system_thread)
DBUG_VOID_RETURN;
if (thd->net.vio)
vio_shutdown(thd->net.vio, SHUT_RD);
DBUG_VOID_RETURN;
}
/* /*
Initialize scheduler for --thread-handling=one-thread-per-connection Initialize scheduler for --thread-handling=one-thread-per-connection
*/ */
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
void one_thread_per_connection_scheduler(scheduler_functions *func, void one_thread_per_connection_scheduler(scheduler_functions *func,
ulong *arg_max_connections, ulong *arg_max_connections,
uint *arg_connection_count) uint *arg_connection_count)
@ -95,6 +118,7 @@ void one_thread_per_connection_scheduler(scheduler_functions *func,
func->init_new_connection_thread= init_new_connection_handler_thread; func->init_new_connection_thread= init_new_connection_handler_thread;
func->add_connection= create_thread_to_handle_connection; func->add_connection= create_thread_to_handle_connection;
func->end_thread= one_thread_per_connection_end; func->end_thread= one_thread_per_connection_end;
func->post_kill_notification= post_kill_notification;
} }
#endif #endif

View File

@ -78,7 +78,7 @@ void one_thread_per_connection_scheduler(scheduler_functions *func,
void one_thread_scheduler(scheduler_functions *func); void one_thread_scheduler(scheduler_functions *func);
extern void scheduler_init(); extern void scheduler_init();
extern void post_kill_notification(THD *);
/* /*
To be used for pool-of-threads (implemeneted differently on various OSs) To be used for pool-of-threads (implemeneted differently on various OSs)
*/ */

View File

@ -257,7 +257,7 @@ static scheduler_functions tp_scheduler_functions=
tp_add_connection, // add_connection tp_add_connection, // add_connection
tp_wait_begin, // thd_wait_begin tp_wait_begin, // thd_wait_begin
tp_wait_end, // thd_wait_end tp_wait_end, // thd_wait_end
tp_post_kill_notification, // post_kill_notification post_kill_notification, // post_kill_notification
NULL, // end_thread NULL, // end_thread
tp_end // end tp_end // end
}; };

View File

@ -173,7 +173,6 @@ static int create_worker(thread_group_t *thread_group);
static void *worker_main(void *param); static void *worker_main(void *param);
static void check_stall(thread_group_t *thread_group); static void check_stall(thread_group_t *thread_group);
static void connection_abort(connection_t *connection); static void connection_abort(connection_t *connection);
void tp_post_kill_notification(THD *thd);
static void set_wait_timeout(connection_t *connection); static void set_wait_timeout(connection_t *connection);
static void set_next_timeout_check(ulonglong abstime); static void set_next_timeout_check(ulonglong abstime);
static void print_pool_blocked_message(bool); static void print_pool_blocked_message(bool);
@ -444,7 +443,7 @@ static void timeout_check(pool_timer_t *timer)
/* Wait timeout exceeded, kill connection. */ /* Wait timeout exceeded, kill connection. */
mysql_mutex_lock(&thd->LOCK_thd_data); mysql_mutex_lock(&thd->LOCK_thd_data);
thd->killed = KILL_CONNECTION; thd->killed = KILL_CONNECTION;
tp_post_kill_notification(thd); post_kill_notification(thd);
mysql_mutex_unlock(&thd->LOCK_thd_data); mysql_mutex_unlock(&thd->LOCK_thd_data);
} }
else else
@ -1258,21 +1257,6 @@ static void connection_abort(connection_t *connection)
} }
/**
MySQL scheduler callback : kill connection
*/
void tp_post_kill_notification(THD *thd)
{
DBUG_ENTER("tp_post_kill_notification");
if (current_thd == thd || thd->system_thread)
DBUG_VOID_RETURN;
if (thd->net.vio)
vio_shutdown(thd->net.vio, SHUT_RD);
DBUG_VOID_RETURN;
}
/** /**
MySQL scheduler callback: wait begin MySQL scheduler callback: wait begin
*/ */

View File

@ -544,22 +544,6 @@ void tp_end(void)
} }
} }
/**
Notify pool about connection being killed.
*/
void tp_post_kill_notification(THD *thd)
{
if (current_thd == thd)
return; /* There is nothing to do.*/
if (thd->system_thread)
return; /* Will crash if we attempt to kill system thread. */
Vio *vio= thd->net.vio;
vio_shutdown(vio, SD_BOTH);
}
/* /*
Handle read completion/notification. Handle read completion/notification.