Commit 6c76e5a0 authored by Vasil Dimov's avatar Vasil Dimov Committed by Marko Mäkelä

Fix Bug#24605956 SERVER MAY CRASH DUE TO A GLIBC BUG IN HANDLING SHORT-LIVED DETACHED THREADS

Avoid detaching and exiting from threads that may finish before the
caller has returned from pthread_create(). Only exit from such threads,
without detach and join with them later.

Patch submitted by: Laurynas Biveinis <laurynas.biveinis@gmail.com>
RB: 13983
Reviewed by: Sunny Bains <sunny.bains@oracle.com>
parent da76c1bd
......@@ -118,9 +118,19 @@ os_thread_create_func(
os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
/** Exits the current thread. */
/** Waits until the specified thread completes and joins it.
Its return value is ignored.
@param[in,out] thread thread to join */
void
os_thread_exit()
os_thread_join(
os_thread_id_t thread);
/** Exits the current thread.
@param[in] detach if true, the thread will be detached right before
exiting. If false, another thread is responsible for joining this thread */
void
os_thread_exit(
bool detach = true)
UNIV_COLD MY_ATTRIBUTE((noreturn));
/*****************************************************************//**
......
......@@ -161,9 +161,32 @@ os_thread_create_func(
return((os_thread_t)new_thread_id);
}
/** Exits the current thread. */
/** Waits until the specified thread completes and joins it.
Its return value is ignored.
@param[in,out] thread thread to join */
void
os_thread_exit()
os_thread_join(
os_thread_id_t thread)
{
#ifdef _WIN32
/* Do nothing. */
#else
#ifdef UNIV_DEBUG
const int ret =
#endif /* UNIV_DEBUG */
pthread_join(thread, NULL);
/* Waiting on already-quit threads is allowed. */
ut_ad(ret == 0 || ret == ESRCH);
#endif /* _WIN32 */
}
/** Exits the current thread.
@param[in] detach if true, the thread will be detached right before
exiting. If false, another thread is responsible for joining this thread */
void
os_thread_exit(
bool detach)
{
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Thread exits, id "
......@@ -184,7 +207,9 @@ os_thread_exit()
ExitThread(0);
#else
mutex_exit(&thread_mutex);
pthread_detach(pthread_self());
if (detach) {
pthread_detach(pthread_self());
}
pthread_exit(NULL);
#endif
}
......
......@@ -1144,7 +1144,7 @@ fts_parallel_merge(
os_event_set(psort_info->psort_common->merge_event);
psort_info->child_status = FTS_CHILD_EXITING;
os_thread_exit();
os_thread_exit(false);
OS_THREAD_DUMMY_RETURN;
}
......@@ -1157,15 +1157,16 @@ row_fts_start_parallel_merge(
fts_psort_t* merge_info) /*!< in: parallel sort info */
{
int i = 0;
os_thread_id_t thd_id;
/* Kick off merge/insert threads */
for (i = 0; i < FTS_NUM_AUX_INDEX; i++) {
merge_info[i].psort_id = i;
merge_info[i].child_status = 0;
merge_info[i].thread_hdl = os_thread_create(fts_parallel_merge,
(void*) &merge_info[i], &thd_id);
merge_info[i].thread_hdl = os_thread_create(
fts_parallel_merge,
(void*) &merge_info[i],
&merge_info[i].thread_hdl);
}
}
......
......@@ -4875,6 +4875,13 @@ row_merge_build_indexes(
" threads exited when creating"
" FTS index '"
<< indexes[i]->name << "'";
} else {
for (j = 0; j < FTS_NUM_AUX_INDEX;
j++) {
os_thread_join(merge_info[j]
.thread_hdl);
}
}
} else {
/* This cannot report duplicates; an
......
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