static void pthread_for_each_thread(void *arg,
void (*fn)(void *, pthread_descr));
-static void pthread_exited(pthread_descr th);
+static int pthread_exited(pthread_descr th);
/* The server thread managing requests for thread creation and termination */
# if defined(TLS_TCB_AT_TP)
TLS_INIT_TP(self, 0);
#elif defined(TLS_DTV_AT_TP)
- TLS_INIT_TP(self + 1, 0);
+ TLS_INIT_TP((char *)self + TLS_PRE_TCB_SIZE, 0);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
break;
case REQ_THREAD_EXIT:
{
- l4_msgtag_t e;
- L4::Cap<L4::Thread> c;
-
- pthread_exited(request.req_thread);
-
- c = L4::Cap<L4::Thread>(request.req_thread->p_thsem_cap);
- e = L4::Cap<L4::Task>(L4Re::This_task)
- ->unmap(c.fpage(), L4_FP_ALL_SPACES);
-
- c = L4::Cap<L4::Thread>(request.req_thread->p_th_cap);
- e = L4::Cap<L4::Task>(L4Re::This_task)
- ->unmap(c.fpage(), L4_FP_ALL_SPACES);
+ if (!pthread_exited(request.req_thread))
+ {
+ auto th = request.req_thread;
+ /* Thread still waiting to be joined. Only release
+ L4 resources for now. */
+ using L4Re::Util::Auto_cap;
+ Auto_cap<void>::Cap s = L4::Cap<void>(th->p_thsem_cap);
+ th->p_thsem_cap = L4_INVALID_CAP;
+ Auto_cap<void>::Cap t = L4::Cap<void>(th->p_th_cap);
+ th->p_th_cap = L4_INVALID_CAP;
+ }
}
break;
}
# if defined(TLS_TCB_AT_TP)
TLS_INIT_TP(self, 0);
#elif defined(TLS_DTV_AT_TP)
- TLS_INIT_TP(self + 1, 0);
+ TLS_INIT_TP((char *)self + TLS_PRE_TCB_SIZE, 0);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
if (err < 0)
return err;
- if (ds.is_valid())
- {
- err = ds->release();
- if (err < 0)
- return err;
- }
-
L4Re::Util::cap_alloc.free(ds);
return e->rm()->free_area((l4_addr_t)guardaddr);
new_thread_bottom = (char *) map_addr + guardsize;
err = e->rm()->attach(&new_thread_bottom, stacksize, L4Re::Rm::In_area,
- ds, 0);
+ L4::Ipc::make_cap_rw(ds), 0);
if (err < 0)
{
_t->ex_regs(l4_addr_t(__pthread_new_thread_entry), l4_addr_t(_tos), 0);
- if (!(create_flags & PTHREAD_L4_ATTR_NO_START))
+ if (thread->p_start_args.start_routine
+ && !(create_flags & PTHREAD_L4_ATTR_NO_START))
{
l4_sched_param_t sp = l4_sched_param(prio >= 0 ? prio : 2);
sp.affinity = affinity;
/* Handle threads that have exited */
-static void pthread_exited(pthread_descr th)
+static int pthread_exited(pthread_descr th)
{
+ if (th->p_exited)
+ return 0;
+
int detached;
/* Remove thread from list of active threads */
th->p_nextlive->p_prevlive = th->p_prevlive;
restart(__pthread_main_thread);
/* Same logic as REQ_MAIN_THREAD_EXIT. */
}
+
+ return detached;
}
}
th = handle_to_descr(handle);
__pthread_unlock(handle_to_lock(handle));
- pthread_exited(th);
- pthread_free(th);
+ if (!pthread_exited(th))
+ pthread_free(th);
}
/* Send a signal to all running threads */