diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 440d0c5..868b313 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -184,12 +184,15 @@ class System(Apex) //(Processor _processById: 1) resume. //<---- i shouldn't do ths. but, this system causes VM assertion failure. fix it.... self.gcfin_should_exit := true. self.gcfin_sem signal. // wake the gcfin process. + + System _halting. ]. } method(#class,#primitive) _getSig. method(#class,#primitive) _getSigfd. method(#class,#primitive) _setSig: signo. + method(#class,#primitive) _halting. method(#class,#primitive) _popCollectable. method(#class,#primitive) collectGarbage. diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 5b55dfd..0b49bf1 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -3245,6 +3245,18 @@ static moo_pfrc_t pf_system_return_value_to_context (moo_t* moo, moo_mod_t* mod, return MOO_PF_SUCCESS; } +/* ------------------------------------------------------------------ */ +static moo_pfrc_t pf_system_halting (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_evtcb_t* cb; + for (cb = moo->evtcb_list; cb; cb = cb->next) + { + if (cb->halting) cb->halting (moo); + } + MOO_STACK_SETRETTORCV (moo, nargs); + return MOO_PF_SUCCESS; +} + /* ------------------------------------------------------------------ */ static moo_pfrc_t pf_number_scale (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { @@ -4351,6 +4363,7 @@ static pf_t pftab[] = { "System_getUint32", { moo_pf_system_get_uint32, 2, 2 } }, { "System_getUint64", { moo_pf_system_get_uint64, 2, 2 } }, { "System_getUint8", { moo_pf_system_get_uint8, 2, 2 } }, + { "System_halting", { pf_system_halting, 0, 0 } }, { "System_log", { pf_system_log, 2, MA } }, { "System_malloc", { moo_pf_system_malloc, 1, 1 } }, { "System_malloc:", { moo_pf_system_malloc, 1, 1 } }, diff --git a/moo/lib/moo.h b/moo/lib/moo.h index fcb21b5..783d1cf 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1255,13 +1255,14 @@ typedef struct moo_vmprim_t moo_vmprim_t; /* ========================================================================= * CALLBACK MANIPULATION * ========================================================================= */ -typedef void (*moo_cbimpl_t) (moo_t* moo); +typedef void (*moo_evtcb_impl_t) (moo_t* moo); typedef struct moo_evtcb_t moo_evtcb_t; struct moo_evtcb_t { - moo_cbimpl_t gc; - moo_cbimpl_t fini; + moo_evtcb_impl_t gc; + moo_evtcb_impl_t halting; + moo_evtcb_impl_t fini; /* private below */ moo_evtcb_t* prev; diff --git a/moo/lib/std.c b/moo/lib/std.c index 78483a8..8b3ed6d 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -380,6 +380,7 @@ struct xtn_t pthread_mutex_t mtx; pthread_cond_t cnd; pthread_cond_t cnd2; + int halting; #endif } ev; }; @@ -2091,6 +2092,7 @@ static int vm_startup (moo_t* moo) pthread_mutex_init (&xtn->ev.mtx, MOO_NULL); pthread_cond_init (&xtn->ev.cnd, MOO_NULL); pthread_cond_init (&xtn->ev.cnd2, MOO_NULL); + xtn->ev.halting = 0; xtn->iothr.abort = 0; xtn->iothr.up = 0; @@ -2509,7 +2511,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c ts.tv_nsec = ns.nsec; pthread_mutex_lock (&xtn->ev.mtx); - if (xtn->ev.len <= 0) + if (xtn->ev.len <= 0 && !xtn->ev.halting) { /* the event buffer is still empty */ pthread_cond_timedwait (&xtn->ev.cnd2, &xtn->ev.mtx, &ts); @@ -3688,6 +3690,19 @@ static void fini_moo (moo_t* moo) unchain (moo); } +static void halting_moo (moo_t* moo) +{ +#if defined(USE_THREAD) + xtn_t* xtn = GET_XTN(moo); + xtn->ev.halting = 1; + pthread_mutex_unlock (&xtn->ev.mtx); + pthread_cond_signal (&xtn->ev.cnd2); + pthread_mutex_unlock (&xtn->ev.mtx); +#else +# error NOT IMPLEMENTED YET +#endif +} + moo_t* moo_openstd (moo_oow_t xtnsize, const moo_cfgstd_t* cfg, moo_errinf_t* errinfo) { moo_t* moo; @@ -3738,6 +3753,7 @@ static void fini_moo (moo_t* moo) MOO_MEMSET (&evtcb, 0, MOO_SIZEOF(evtcb)); evtcb.fini = fini_moo; + evtcb.halting = halting_moo; moo_regevtcb (moo, &evtcb);