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:
parent
a9a0bbad19
commit
12c407a424
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user