From 37e7e911d7ca49b327a987582e5f4cce44a4f14b Mon Sep 17 00:00:00 2001 From: Ted Unangst Date: Wed, 21 Dec 2005 00:49:08 +0000 Subject: check a few remaining mallocs for failure, along with mmap and rfork started by miod --- lib/librthread/rthread.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'lib/librthread/rthread.c') diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index 43c88a82455..e4218e7bd3f 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.11 2005/12/19 15:41:00 brad Exp $ */ +/* $OpenBSD: rthread.c,v 1.12 2005/12/21 00:49:07 tedu Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst * All Rights Reserved. @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,8 @@ thread_init(void) __isthreaded = 1; thread = malloc(sizeof(*thread)); + if (!thread) /* should never happen, but have to do something */ + err(1, "rthread_init"); memset(thread, 0, sizeof(*thread)); thread->tid = getthrid(); thread->donesem.lock = _SPINLOCK_UNLOCKED; @@ -117,11 +120,25 @@ alloc_stack(size_t len) struct stack *stack; stack = malloc(sizeof(*stack)); + if (!stack) + return (NULL); stack->base = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (stack->base == MAP_FAILED) { + free(stack); + return (NULL); + } stack->sp = (void *)(((size_t)stack->base + len - 16) & ~15); + stack->len = len; return (stack); } +static void +free_stack(struct stack *stack) +{ + munmap(stack->base, stack->len); + free(stack); +} + /* * real pthread functions */ @@ -196,31 +213,51 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr, { pthread_t thread; pid_t tid; + int rc = 0; if (!threads_ready) thread_init(); thread = malloc(sizeof(*thread)); + if (!thread) + return (errno); memset(thread, 0, sizeof(*thread)); + thread->stack = alloc_stack(64 * 1024); + if (!thread->stack) { + rc = errno; + goto fail1; + } + thread->donesem.lock = _SPINLOCK_UNLOCKED; thread->fn = start_routine; thread->arg = arg; _spinlock(&thread_lock); + thread->next = thread_list; thread_list = thread; - thread->stack = alloc_stack(64 * 1024); - tid = rfork_thread(RFPROC | RFTHREAD | RFMEM | RFNOWAIT, thread->stack->sp, thread_start, thread); + if (tid == -1) { + rc = errno; + goto fail2; + } /* new thread will appear thread_start */ thread->tid = tid; thread->flags |= THREAD_CANCEL_ENABLE|THREAD_CANCEL_DEFERRED; *threadp = thread; _spinunlock(&thread_lock); - return (0); + +fail2: + thread_list = thread->next; + _spinunlock(&thread_lock); + free_stack(thread->stack); +fail1: + free(thread); + + return (rc); } int -- cgit v1.2.3