Return gracefully, rather than aborting, when the maximum concurrent

threads per process has been reached. Return EAGAIN, as per spec.

Approved by:	re/blanket libthr
This commit is contained in:
Mike Makonnen 2003-05-25 22:40:57 +00:00
parent a9a0bbad19
commit 12c407a424
6 changed files with 27 additions and 10 deletions

View File

@ -87,13 +87,15 @@ _retire_thread(void *entry)
}
void *
_set_curthread(ucontext_t *uc, struct pthread *thr)
_set_curthread(ucontext_t *uc, struct pthread *thr, int *err)
{
union descriptor desc;
void **ldt_entry;
int ldt_index;
int error;
*err = 0;
/*
* If we are setting up the initial thread, the gs register
* won't be setup for the current thread. In any case, we
@ -106,8 +108,11 @@ _set_curthread(ucontext_t *uc, struct pthread *thr)
if (ldt_inited == NULL)
ldt_init();
if (ldt_free == NULL)
abort();
if (ldt_free == NULL) {
/* Concurrent thread limit reached */
*err = curthread->error = EAGAIN;
return (NULL);
}
/*
* Pull one off of the free list and update the free list pointer.

View File

@ -48,9 +48,9 @@ _retire_thread(void *v)
}
void *
_set_curthread(ucontext_t *uc, struct pthread *thread)
_set_curthread(ucontext_t *uc, struct pthread *thread, int *err)
{
*err = 0;
if (uc != NULL)
uc->uc_mcontext.mc_special.tp = (uint64_t)thread;
else

View File

@ -48,9 +48,9 @@ _retire_thread(void *v)
}
void *
_set_curthread(ucontext_t *uc, struct pthread *thread)
_set_curthread(ucontext_t *uc, struct pthread *thread, int *err)
{
*err = 0;
if (uc != NULL)
uc->uc_mcontext.mc_global[6] = (uint64_t)thread;
else

View File

@ -116,7 +116,18 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
new_thread->ctx.uc_stack.ss_sp = new_thread->stack;
new_thread->ctx.uc_stack.ss_size = pattr->stacksize_attr;
makecontext(&new_thread->ctx, _thread_start, 0);
new_thread->arch_id = _set_curthread(&new_thread->ctx, new_thread);
new_thread->arch_id = _set_curthread(&new_thread->ctx, new_thread, &ret);
if (ret != 0) {
if (pattr->stackaddr_attr == NULL) {
/* XXX - We really need to decouple from this lock */
DEAD_LIST_LOCK;
_thread_stack_free(new_thread->stack,
pattr->stacksize_attr, pattr->guardsize_attr);
DEAD_LIST_UNLOCK;
}
free(new_thread);
return (ret);
}
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));

View File

@ -162,6 +162,7 @@ _thread_init(void)
size_t len;
int mib[2];
sigset_t set;
int error;
struct clockinfo clockinfo;
struct sigaction act;
@ -221,7 +222,7 @@ _thread_init(void)
memset(pthread, 0, sizeof(struct pthread));
_thread_initial = pthread;
pthread->arch_id = _set_curthread(NULL, pthread);
pthread->arch_id = _set_curthread(NULL, pthread, &error);
/* Get our thread id. */
thr_self(&pthread->thr_id);

View File

@ -711,7 +711,7 @@ char *ttyname_r(int, char *, size_t);
void _cond_wait_backout(pthread_t);
int _find_thread(pthread_t);
pthread_t _get_curthread(void);
void *_set_curthread(ucontext_t *, struct pthread *);
void *_set_curthread(ucontext_t *, struct pthread *, int *);
void _retire_thread(void *arch_id);
void *_thread_stack_alloc(size_t, size_t);
void _thread_stack_free(void *, size_t, size_t);