From e54ec2f5c366fcf32d9568066c2f2828dd2fe3e7 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 24 Jun 2014 01:20:31 +0000 Subject: [PATCH] rculfhash: handle pthread_create failures Like calloc, pthread_create may fail with EAGAIN due to a lack of resources. Account for that and gracefully continue. Signed-off-by: Eric Wong Signed-off-by: Mathieu Desnoyers --- rculfhash.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/rculfhash.c b/rculfhash.c index 2a45045..8a8ede7 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -1171,7 +1171,7 @@ void partition_resize_helper(struct cds_lfht *ht, unsigned long i, void (*fct)(struct cds_lfht *ht, unsigned long i, unsigned long start, unsigned long len)) { - unsigned long partition_len; + unsigned long partition_len, start = 0; struct partition_resize_work *work; int thread, ret; unsigned long nr_threads; @@ -1201,6 +1201,17 @@ void partition_resize_helper(struct cds_lfht *ht, unsigned long i, work[thread].fct = fct; ret = pthread_create(&(work[thread].thread_id), ht->resize_attr, partition_resize_thread, &work[thread]); + if (ret == EAGAIN) { + /* + * Out of resources: wait and join the threads + * we've created, then handle leftovers. + */ + dbg_printf("error spawning for resize, single-threading\n"); + start = work[thread].start; + len -= start; + nr_threads = thread; + break; + } assert(!ret); } for (thread = 0; thread < nr_threads; thread++) { @@ -1208,10 +1219,17 @@ void partition_resize_helper(struct cds_lfht *ht, unsigned long i, assert(!ret); } free(work); - return; + + /* + * A pthread_create failure above will either lead in us having + * no threads to join or starting at a non-zero offset, + * fallback to single thread processing of leftovers. + */ + if (start == 0 && nr_threads > 0) + return; fallback: ht->flavor->thread_online(); - fct(ht, i, 0, len); + fct(ht, i, start, len); ht->flavor->thread_offline(); } -- 2.34.1