glibc-2.32 contains new code to prevent a race conditions with signals in pthread_create.
Unified · Split
| @@ -1242,46 +1242,53 @@ void __attribute__((destructor)) __bound_exit(void) · 1241 unmodified lines | ||
| 1242 | 1242 | } |
| 1243 | 1243 | |
| 1244 | 1244 | #if HAVE_PTHREAD_CREATE |
| 1245 | −#if HAVE_TLS_FUNC | |
| 1246 | 1245 | typedef struct { |
| 1247 | 1246 | void *(*start_routine) (void *); |
| 1248 | 1247 | void *arg; |
| 1248 | + sigset_t old_mask; | |
| 1249 | 1249 | } bound_thread_create_type; |
| 1250 | 1250 | |
| 1251 | 1251 | static void *bound_thread_create(void *bdata) |
| 1252 | 1252 | { |
| 1253 | 1253 | bound_thread_create_type *data = (bound_thread_create_type *) bdata; |
| 1254 | 1254 | void *retval; |
| 1255 | +#if HAVE_TLS_FUNC | |
| 1255 | 1256 | int *p = (int *) BOUND_MALLOC(sizeof(int)); |
| 1256 | 1257 | |
| 1257 | 1258 | if (!p) bound_alloc_error("bound_thread_create malloc"); |
| 1258 | 1259 | *p = 0; |
| 1259 | 1260 | pthread_setspecific(no_checking_key, p); |
| 1261 | +#endif | |
| 1262 | + pthread_sigmask(SIG_SETMASK, &data->old_mask, NULL); | |
| 1260 | 1263 | retval = data->start_routine(data->arg); |
| 1264 | +#if HAVE_TLS_FUNC | |
| 1261 | 1265 | pthread_setspecific(no_checking_key, NULL); |
| 1262 | 1266 | BOUND_FREE (p); |
| 1267 | +#endif | |
| 1263 | 1268 | BOUND_FREE (data); |
| 1264 | 1269 | return retval; |
| 1265 | 1270 | } |
| 1266 | −#endif | |
| 1267 | 1271 | |
| 1268 | 1272 | int pthread_create(pthread_t *thread, const pthread_attr_t *attr, |
| 1269 | 1273 | void *(*start_routine) (void *), void *arg) |
| 1270 | 1274 | { |
| 1275 | + int retval; | |
| 1276 | + bound_thread_create_type *data; | |
| 1277 | + sigset_t mask; | |
| 1278 | + sigset_t old_mask; | |
| 1279 | + | |
| 1271 | 1280 | use_sem = 1; |
| 1272 | 1281 | dprintf (stderr, "%s, %s()\n", __FILE__, __FUNCTION__); |
| 1273 | −#if HAVE_TLS_FUNC | |
| 1274 | − { | |
| 1275 | − bound_thread_create_type *data; | |
| 1276 | − | |
| 1277 | − data = (bound_thread_create_type *) BOUND_MALLOC(sizeof(bound_thread_create_type)); | |
| 1278 | − data->start_routine = start_routine; | |
| 1279 | − data->arg = arg; | |
| 1280 | − return pthread_create_redir(thread, attr, bound_thread_create, data); | |
| 1281 | − } | |
| 1282 | −#else | |
| 1283 | − return pthread_create_redir(thread, attr, start_routine, arg); | |
| 1284 | −#endif | |
| 1282 | + sigfillset(&mask); | |
| 1283 | + pthread_sigmask(SIG_SETMASK, &mask, &old_mask); | |
| 1284 | + data = (bound_thread_create_type *) BOUND_MALLOC(sizeof(bound_thread_create_type)); | |
| 1285 | + if (!data) bound_alloc_error("bound_thread_create malloc"); | |
| 1286 | + data->start_routine = start_routine; | |
| 1287 | + data->arg = arg; | |
| 1288 | + data->old_mask = old_mask; | |
| 1289 | + retval = pthread_create_redir(thread, attr, bound_thread_create, data); | |
| 1290 | + pthread_sigmask(SIG_SETMASK, &old_mask, NULL); | |
| 1291 | + return retval; | |
| 1285 | 1292 | } |
| 1286 | 1293 | #endif |
| 1287 | 1294 | |
| @@ -107,7 +107,7 @@ main (void) · 106 unmodified lines | ||
| 107 | 107 | sem_init (&sem_child, 0, 0); |
| 108 | 108 | pthread_create(&id1, NULL, high_load, NULL); |
| 109 | 109 | pthread_create(&id2, NULL, do_signal, NULL); |
| 110 | −#if !defined(__arm__) && !defined(__APPLE__) | |
| 110 | +#if !defined(__APPLE__) | |
| 111 | 111 | pthread_create(&id3, NULL, do_fork, NULL); |
| 112 | 112 | #endif |
| 113 | 113 | |
| @@ -120,7 +120,7 @@ main (void) · 6 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | pthread_join(id1, NULL); |
| 122 | 122 | pthread_join(id2, NULL); |
| 123 | −#if !defined(__arm__) && !defined(__APPLE__) | |
| 123 | +#if !defined(__APPLE__) | |
| 124 | 124 | pthread_join(id3, NULL); |
| 125 | 125 | #endif |
| 126 | 126 | sem_destroy (&sem); |