Skip to content

Commit cea437f

Browse files
committed
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 <[email protected]> RB: 13983 Reviewed by: Sunny Bains <[email protected]>
1 parent 96bb62f commit cea437f

File tree

4 files changed

+49
-5
lines changed

4 files changed

+49
-5
lines changed

storage/innobase/include/os0thread.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,25 @@ os_thread_create_func(
117117
os_thread_id_t* thread_id); /*!< out: id of the created
118118
thread, or NULL */
119119

120+
/** Waits until the specified thread completes and joins it.
121+
Its return value is ignored.
122+
@param[in,out] thread thread to join */
123+
UNIV_INTERN
124+
void
125+
os_thread_join(
126+
os_thread_t thread);
127+
120128
/*****************************************************************//**
121129
Exits the current thread. */
122130
UNIV_INTERN
123131
void
124132
os_thread_exit(
125133
/*===========*/
126-
void* exit_value) /*!< in: exit value; in Windows this void*
134+
void* exit_value, /*!< in: exit value; in Windows this void*
127135
is cast as a DWORD */
136+
bool detach = true) /*!< in: if true, the thread will be detached
137+
right before exiting. If false, another thread
138+
is responsible for joining this thread. */
128139
UNIV_COLD MY_ATTRIBUTE((noreturn));
129140
/*****************************************************************//**
130141
Returns the thread identifier of current thread.

storage/innobase/os/os0thread.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -191,14 +191,38 @@ os_thread_create_func(
191191
#endif
192192
}
193193

194+
/** Waits until the specified thread completes and joins it.
195+
Its return value is ignored.
196+
@param[in,out] thread thread to join */
197+
UNIV_INTERN
198+
void
199+
os_thread_join(
200+
os_thread_t thread)
201+
{
202+
#ifdef __WIN__
203+
/* Do nothing. */
204+
#else
205+
#ifdef UNIV_DEBUG
206+
const int ret =
207+
#endif /* UNIV_DEBUG */
208+
pthread_join(thread, NULL);
209+
210+
/* Waiting on already-quit threads is allowed. */
211+
ut_ad(ret == 0 || ret == ESRCH);
212+
#endif /* __WIN__ */
213+
}
214+
194215
/*****************************************************************//**
195216
Exits the current thread. */
196217
UNIV_INTERN
197218
void
198219
os_thread_exit(
199220
/*===========*/
200-
void* exit_value) /*!< in: exit value; in Windows this void*
221+
void* exit_value, /*!< in: exit value; in Windows this void*
201222
is cast as a DWORD */
223+
bool detach) /*!< in: if true, the thread will be detached
224+
right before exiting. If false, another thread
225+
is responsible for joining this thread. */
202226
{
203227
#ifdef UNIV_DEBUG_THREAD_CREATION
204228
fprintf(stderr, "Thread exits, id %lu\n",
@@ -216,7 +240,9 @@ os_thread_exit(
216240
#ifdef __WIN__
217241
ExitThread((DWORD) exit_value);
218242
#else
219-
pthread_detach(pthread_self());
243+
if (detach) {
244+
pthread_detach(pthread_self());
245+
}
220246
pthread_exit(exit_value);
221247
#endif
222248
}

storage/innobase/row/row0ftsort.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ fts_parallel_merge(
957957
CloseHandle(psort_info->thread_hdl);
958958
#endif /*__WIN__ */
959959

960-
os_thread_exit(NULL);
960+
os_thread_exit(NULL, false);
961961

962962
OS_THREAD_DUMMY_RETURN;
963963
}

storage/innobase/row/row0merge.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,6 +3774,13 @@ row_merge_build_indexes(
37743774
" exited when creating FTS"
37753775
" index '%s'",
37763776
indexes[i]->name);
3777+
} else {
3778+
for (j = 0; j < FTS_NUM_AUX_INDEX;
3779+
j++) {
3780+
3781+
os_thread_join(merge_info[j]
3782+
.thread_hdl);
3783+
}
37773784
}
37783785
} else {
37793786
/* This cannot report duplicates; an

0 commit comments

Comments
 (0)