void coopth_detach(void) { struct coopth_thrdata_t *thdata; assert(_coopth_is_in_thread()); thdata = co_get_data(co_current()); ensure_single(thdata); if (!thdata->attached) return; switch_state(COOPTH_DETACH); }
/* for some time coopth_leave() was implemented on top of coopth_detach(). * This appeared not the best implementation. In particular, the commit * 551371689 was needed to make leaving operation atomic, but this is * not needed for detached threads at all. While the detached threads * has a separate entry point (via coopth_run()), the left thread must * not have a separate entry point. So it appeared better to return the * special type "left" threads. * Additionally the leave operation now calls the post handler immediately. */ void coopth_leave(void) { struct coopth_thrdata_t *thdata; if (!_coopth_is_in_thread_nowarn()) return; thdata = co_get_data(co_current()); ensure_single(thdata); if (thdata->left) return; switch_state(COOPTH_LEAVE); }
/* for some time coopth_leave() was implemented on top of coopth_detach(). * This appeared not the best implementation. In particular, the commit * 551371689 was needed to make leaving operation atomic, but this is * not needed for detached threads at all. While the detached threads * has a separate entry point (via coopth_run()), the left thread must * not have a separate entry point. So it appeared better to return the * special type "left" threads. * Additionally the leave operation now calls the post handler immediately, * and it should be called from the context of the main thread. This is * the reason why coopth_leave() for detached thread cannot be a no-op. */ void coopth_leave(void) { struct coopth_thrdata_t *thdata; if (!_coopth_is_in_thread_nowarn()) return; thdata = co_get_data(co_current()); ensure_single(thdata); if (thdata->left) return; /* leaving detached thread should be atomic even wrt other detached * threads. This is needed so that DPMI cannot run concurrently with * leavedos(). * for joinable threads leaving should be atomic only wrt DOS code, * but, because of an optimization loop in run_vm86(), it is actually * also atomic wrt detached threads. */ if (!thdata->attached) thdata->atomic_switch = 1; switch_state(COOPTH_LEAVE); }