diff --git a/moo/Makefile.in b/moo/Makefile.in index 9e029b0..2105b34 100644 --- a/moo/Makefile.in +++ b/moo/Makefile.in @@ -355,6 +355,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -585,7 +586,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -611,7 +612,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -629,7 +630,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -639,7 +640,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/moo/configure b/moo/configure index 3014b96..d303ef0 100755 --- a/moo/configure +++ b/moo/configure @@ -791,6 +791,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -887,6 +888,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1139,6 +1141,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1276,7 +1287,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1429,6 +1440,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -18372,6 +18384,18 @@ _ACEOF fi done +for ac_func in sigaction signal +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + for ac_func in snprintf _vsnprintf _vsnwprintf strerror_r do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -21039,6 +21063,11 @@ _ACEOF fi +cat >>confdefs.h <<_ACEOF +#define MOO_NSIG ${ax_cv_numvalof_NSIG} +_ACEOF + + cat >>confdefs.h <<_ACEOF #define MOO_SIZEOF_STRUCT_SOCKADDR_IN ${ac_cv_sizeof_struct_sockaddr_in} diff --git a/moo/configure.ac b/moo/configure.ac index ea5be41..8695616 100644 --- a/moo/configure.ac +++ b/moo/configure.ac @@ -153,6 +153,7 @@ AC_CHECK_FUNCS([backtrace backtrace_symbols]) AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext]) AC_CHECK_FUNCS([clock_nanosleep nanosleep usleep]) AC_CHECK_FUNCS([localtime_r gmtime_r]) +AC_CHECK_FUNCS([sigaction signal]) AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf strerror_r]) AC_CHECK_FUNCS([accept4 pipe2 epoll_create1]) AC_CHECK_FUNCS([isatty mmap munmap]) @@ -587,6 +588,7 @@ if test ${ax_cv_numvalof_PATH_MAX} -gt 0 then AC_DEFINE_UNQUOTED(MOO_PATH_MAX, ${ax_cv_numvalof_PATH_MAX}, [PATH_MAX]) fi +AC_DEFINE_UNQUOTED(MOO_NSIG, ${ax_cv_numvalof_NSIG}, [NSIG]) AC_DEFINE_UNQUOTED(MOO_SIZEOF_STRUCT_SOCKADDR_IN, ${ac_cv_sizeof_struct_sockaddr_in}, [sizeof(struct sockaddr_in)]) AC_DEFINE_UNQUOTED(MOO_SIZEOF_STRUCT_SOCKADDR_IN6, ${ac_cv_sizeof_struct_sockaddr_in6}, [sizeof(struct sockaddr_in6)]) diff --git a/moo/lib/Makefile.in b/moo/lib/Makefile.in index 57d7a04..ecf645b 100644 --- a/moo/lib/Makefile.in +++ b/moo/lib/Makefile.in @@ -404,6 +404,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/moo/lib/main.c b/moo/lib/main.c index f1d4e3c..f5052a6 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -116,208 +116,8 @@ static MOO_INLINE void abort_moo (void) if (g_moo) moo_abortstd (g_moo); } -static MOO_INLINE void swproc_moo (void) -{ - if (g_moo) moo_switchprocess (g_moo); -} - /* ========================================================================= */ -#if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) - -#if defined(_INTELC32_) -static void (*prev_timer_intr_handler) (void); -#else -static void (__interrupt *prev_timer_intr_handler) (void); -#endif - -#if defined(_INTELC32_) -#pragma interrupt(timer_intr_handler) -static void timer_intr_handler (void) -#else -static void __interrupt timer_intr_handler (void) -#endif -{ - /* - _XSTACK *stk; - int r; - stk = (_XSTACK *)_get_stk_frame(); - r = (unsigned short)stk_ptr->eax; - */ - - /* The timer interrupt (normally) occurs 18.2 times per second. */ - swproc_moo (); - _chain_intr (prev_timer_intr_handler); -} - - -static void setup_tick (void) -{ - prev_timer_intr_handler = _dos_getvect (0x1C); - _dos_setvect (0x1C, timer_intr_handler); -} - -static void cancel_tick (void) -{ - _dos_setvect (0x1C, prev_timer_intr_handler); -} - -#elif defined(_WIN32) - -static HANDLE g_tick_timer = MOO_NULL; /*INVALID_HANDLE_VALUE;*/ - -static VOID CALLBACK arrange_process_switching (LPVOID arg, DWORD timeLow, DWORD timeHigh) -{ - swproc_moo (); -} - -static void setup_tick (void) -{ - LARGE_INTEGER li; - g_tick_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL); - if (g_tick_timer) - { - li.QuadPart = -MOO_SECNSEC_TO_NSEC(0, 20000); /* 20000 microseconds. 0.02 seconds */ - SetWaitableTimer (g_tick_timer, &li, 0, arrange_process_switching, MOO_NULL, FALSE); - } -} - -static void cancel_tick (void) -{ - if (g_tick_timer) - { - CancelWaitableTimer (g_tick_timer); - CloseHandle (g_tick_timer); - g_tick_timer = MOO_NULL; - } -} - -#elif defined(__OS2__) -static TID g_tick_tid; -static HEV g_tick_sem; -static HTIMER g_tick_timer; -static int g_tick_done = 0; - -static void EXPENTRY os2_wait_for_timer_event (ULONG x) -{ - APIRET rc; - ULONG count; - - rc = DosCreateEventSem (NULL, &g_tick_sem, DC_SEM_SHARED, FALSE); - if (rc != NO_ERROR) - { - /* xxxx */ - } - - rc = DosStartTimer (1L, (HSEM)g_tick_sem, &g_tick_timer); - if (rc != NO_ERROR) - { - } - - while (!g_tick_done) - { - rc = DosWaitEventSem((HSEM)g_tick_sem, 5000L); - DosResetEventSem((HSEM)g_tick_sem, &count); - swproc_moo (); - } - - DosStopTimer (g_tick_timer); - DosCloseEventSem ((HSEM)g_tick_sem); - - g_tick_timer = NULL; - g_tick_sem = NULL; - DosExit (EXIT_THREAD, 0); -} - -static void setup_tick (void) -{ - /* TODO: Error check */ - DosCreateThread (&g_tick_tid, os2_wait_for_timer_event, 0, 0, 4096); -} - -static void cancel_tick (void) -{ - if (g_tick_sem) DosPostEventSem (g_tick_sem); - g_tick_done = 1; -} - -#elif defined(macintosh) - -static TMTask g_tmtask; -static ProcessSerialNumber g_psn; - -#define TMTASK_DELAY 50 /* milliseconds if positive, microseconds(after negation) if negative */ - -static pascal void timer_intr_handler (TMTask* task) -{ - swproc_moo (); - WakeUpProcess (&g_psn); - PrimeTime ((QElem*)&g_tmtask, TMTASK_DELAY); -} - -static void setup_tick (void) -{ - GetCurrentProcess (&g_psn); - memset (&g_tmtask, 0, MOO_SIZEOF(g_tmtask)); - g_tmtask.tmAddr = NewTimerProc (timer_intr_handler); - InsXTime ((QElem*)&g_tmtask); - PrimeTime ((QElem*)&g_tmtask, TMTASK_DELAY); -} - -static void cancel_tick (void) -{ - RmvTime ((QElem*)&g_tmtask); - /*DisposeTimerProc (g_tmtask.tmAddr);*/ -} - -#elif defined(HAVE_SETITIMER) && defined(SIGVTALRM) && defined(ITIMER_VIRTUAL) - -static void arrange_process_switching (int sig) -{ - swproc_moo (); -} - -static void setup_tick (void) -{ - struct itimerval itv; - struct sigaction act, oldact; - - memset (&act, 0, sizeof(act)); - sigemptyset (&act.sa_mask); - act.sa_handler = arrange_process_switching; - act.sa_flags = SA_RESTART; - sigaction (SIGVTALRM, &act, MOO_NULL); - -/*#define MOO_ITIMER_TICK 10000*/ /* microseconds. 0.01 seconds */ -#define MOO_ITIMER_TICK 20000 /* microseconds. 0.02 seconds. */ - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = MOO_ITIMER_TICK; - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = MOO_ITIMER_TICK; - setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); -} - -static void cancel_tick (void) -{ - struct itimerval itv; - struct sigaction act; - - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 0; - itv.it_value.tv_sec = 0; /* make setitimer() one-shot only */ - itv.it_value.tv_usec = 0; - setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); - - sigemptyset (&act.sa_mask); - act.sa_handler = SIG_IGN; /* ignore the signal potentially fired by the one-shot arrange above */ - act.sa_flags = 0; - sigaction (SIGVTALRM, &act, MOO_NULL); -} -#else -# error UNSUPPORTED -#endif - - #if defined(_WIN32) static BOOL WINAPI handle_term (DWORD ctrl_type) { @@ -627,9 +427,11 @@ int main (int argc, char* argv[]) MOO_DEBUG0 (moo, "COMPILE OK. STARTING EXECUTION...\n"); xret = 0; g_moo = moo; - setup_tick (); + moo_start_ticker (); setup_sigterm (); + moo_rcvtickstd (moo, 1); + objname.ptr = str_my_object; objname.len = 8; mthname.ptr = str_main; @@ -640,7 +442,7 @@ int main (int argc, char* argv[]) xret = -1; } - cancel_tick (); + moo_stop_ticker (); clear_sigterm (); g_moo = MOO_NULL; diff --git a/moo/lib/moo-cfg.h.in b/moo/lib/moo-cfg.h.in index 8141ec4..801cfd3 100644 --- a/moo/lib/moo-cfg.h.in +++ b/moo/lib/moo-cfg.h.in @@ -174,6 +174,12 @@ /* Define to 1 if you have the `settimeofday' function. */ #undef HAVE_SETTIMEOFDAY +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `signal' function. */ +#undef HAVE_SIGNAL + /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H @@ -348,6 +354,9 @@ /* MB_LEN_MAX */ #undef MOO_MBLEN_MAX +/* NSIG */ +#undef MOO_NSIG + /* offsetof(struct sockaddr, sa_family) */ #undef MOO_OFFSETOF_SA_FAMILY diff --git a/moo/lib/moo-std.h b/moo/lib/moo-std.h index 8322082..48f157c 100644 --- a/moo/lib/moo-std.h +++ b/moo/lib/moo-std.h @@ -78,6 +78,14 @@ typedef struct moo_iostd_t moo_iostd_t; extern "C" { #endif +MOO_EXPORT void moo_start_ticker ( + void +); + +MOO_EXPORT void moo_stop_ticker ( + void +); + MOO_EXPORT moo_t* moo_openstd ( moo_oow_t xtnsize, const moo_cfgstd_t* cfg, @@ -97,6 +105,12 @@ MOO_EXPORT int moo_compilestd( const moo_iostd_t* in, moo_oow_t count ); + +MOO_EXPORT void moo_rcvtickstd ( + moo_t* moo, + int v +); + #if defined(__cplusplus) } #endif diff --git a/moo/lib/std.c b/moo/lib/std.c index 021c0d2..fadc844 100644 --- a/moo/lib/std.c +++ b/moo/lib/std.c @@ -265,6 +265,7 @@ struct xtn_t moo_t* prev; int vm_running; + int rcv_tick; struct { @@ -359,7 +360,6 @@ struct xtn_t #define GET_XTN(moo) ((xtn_t*)moo_getxtn(moo)) static moo_t* g_moo = MOO_NULL; -static int g_moo_tick_active = 0; /* ========================================================================= */ @@ -2604,6 +2604,8 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur) /* ========================================================================= */ +#if defined(HAVE_SIGACTION) + typedef struct sig_state_t sig_state_t; struct sig_state_t { @@ -2615,14 +2617,16 @@ struct sig_state_t typedef void (*sig_handler_t) (int sig); -#if !defined(NSIGS) -# define NSIGS 100 /* TODO: change this */ -#endif -static sig_state_t g_sig_state[NSIGS]; +static sig_state_t g_sig_state[MOO_NSIG]; static void dispatch_siginfo (int sig, siginfo_t* si, void* ctx) { - ((sig_handler_t)g_sig_state[sig].handler) (sig); + if (g_sig_state[sig].handler != (moo_oow_t)SIG_IGN && + g_sig_state[sig].handler != (moo_oow_t)SIG_DFL) + { + ((sig_handler_t)g_sig_state[sig].handler) (sig); + } + if (g_sig_state[sig].old_handler && g_sig_state[sig].old_handler != (moo_oow_t)SIG_IGN && g_sig_state[sig].old_handler != (moo_oow_t)SIG_DFL) @@ -2633,7 +2637,12 @@ static void dispatch_siginfo (int sig, siginfo_t* si, void* ctx) static void dispatch_signal (int sig) { - ((sig_handler_t)g_sig_state[sig].handler) (sig); + if (g_sig_state[sig].handler != (moo_oow_t)SIG_IGN && + g_sig_state[sig].handler != (moo_oow_t)SIG_DFL) + { + ((sig_handler_t)g_sig_state[sig].handler) (sig); + } + if (g_sig_state[sig].old_handler && g_sig_state[sig].old_handler != (moo_oow_t)SIG_IGN && g_sig_state[sig].old_handler != (moo_oow_t)SIG_DFL) @@ -2647,6 +2656,7 @@ static int set_signal_handler (int sig, sig_handler_t handler, int extra_flags) if (g_sig_state[sig].handler) { /* already set - allow handler change. ignore extra_flags. */ + if (g_sig_state[sig].handler == (moo_oow_t)handler) return -1; g_sig_state[sig].handler = (moo_oow_t)handler; } else @@ -2713,9 +2723,10 @@ static int unset_signal_handler (int sig) return 0; } +#endif /* ========================================================================= */ -static MOO_INLINE void swproc_all (void) +static MOO_INLINE void swproc_all_moos (void) { /* TODO: make this atomic */ if (g_moo) @@ -2723,15 +2734,15 @@ static MOO_INLINE void swproc_all (void) moo_t* moo = g_moo; do { - moo_switchprocess (moo); - moo = GET_XTN(moo)->next; + xtn_t* xtn = GET_XTN(moo); + if (xtn->rcv_tick) moo_switchprocess (moo); + moo = xtn->next; } while (moo); } /* TODO: make this atomic */ } - #if defined(__DOS__) && (defined(_INTELC32_) || defined(__WATCOMC__)) #if defined(_INTELC32_) @@ -2755,48 +2766,61 @@ static void __interrupt dos_timer_intr_handler (void) */ /* The timer interrupt (normally) occurs 18.2 times per second. */ - swproc_moo (); + swproc_all_moos (); _chain_intr (dos_prev_timer_intr_handler); } -static void setup_tick (void) +static void moo_start_ticker (void) { - dos_prev_timer_intr_handler = _dos_getvect(0x1C); - _dos_setvect (0x1C, dos_timer_intr_handler); + if (++ticker_started == 1) + { + dos_prev_timer_intr_handler = _dos_getvect(0x1C); + _dos_setvect (0x1C, dos_timer_intr_handler); + } } -static void cancel_tick (void) +static void moo_stop_ticker (void) { - _dos_setvect (0x1C, dos_prev_timer_intr_handler); + if (ticker_started > 0 && --ticker_started == 0) + { + _dos_setvect (0x1C, dos_prev_timer_intr_handler); + } } #elif defined(_WIN32) static HANDLE win_tick_timer = MOO_NULL; /*INVALID_HANDLE_VALUE;*/ +static moo_uint32_t ticker_started = 0; static VOID CALLBACK arrange_process_switching (LPVOID arg, DWORD timeLow, DWORD timeHigh) { - swproc_moo (); + swproc_all_moos (); } -static void setup_tick (void) +static void moo_start_ticker (void) { - LARGE_INTEGER li; - win_tick_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL); - if (win_tick_timer) + if (++ticker_started == 1) { - li.QuadPart = -MOO_SECNSEC_TO_NSEC(0, 20000); /* 20000 microseconds. 0.02 seconds */ - SetWaitableTimer (win_tick_timer, &li, 0, arrange_process_switching, MOO_NULL, FALSE); + LARGE_INTEGER li; + win_tick_timer = CreateWaitableTimer(MOO_NULL, TRUE, MOO_NULL); + if (win_tick_timer) + { + li.QuadPart = -MOO_SECNSEC_TO_NSEC(0, 20000); /* 20000 microseconds. 0.02 seconds */ + SetWaitableTimer (win_tick_timer, &li, 0, arrange_process_switching, MOO_NULL, FALSE); + } } } -static void cancel_tick (void) +static void moo_stop_ticker (void) { - if (win_tick_timer) + if (ticker_started > 0 && --ticker_started == 0) { - CancelWaitableTimer (win_tick_timer); - CloseHandle (win_tick_timer); - win_tick_timer = MOO_NULL; + if (win_tick_timer) + { + CancelWaitableTimer (win_tick_timer); + CloseHandle (win_tick_timer); + win_tick_timer = MOO_NULL; + } } } @@ -2805,6 +2829,7 @@ static TID os2_tick_tid; static HEV os2_tick_sem; static HTIMER os2_tick_timer; static int os2_tick_done = 0; +static moo_uint32_t ticker_started = 0; static void EXPENTRY os2_wait_for_timer_event (ULONG x) { @@ -2826,7 +2851,7 @@ static void EXPENTRY os2_wait_for_timer_event (ULONG x) { rc = DosWaitEventSem((HSEM)os2_tick_sem, 5000L); DosResetEventSem((HSEM)os2_tick_sem, &count); - swproc_moo (); + swproc_all_moos (); } DosStopTimer (os2_tick_timer); @@ -2837,16 +2862,22 @@ static void EXPENTRY os2_wait_for_timer_event (ULONG x) DosExit (EXIT_THREAD, 0); } -static void setup_tick (void) +static void moo_start_ticker (void) { - /* TODO: Error check */ - DosCreateThread (&os2_tick_tid, os2_wait_for_timer_event, 0, 0, 4096); + if (++ticker_started == 1) + { + /* TODO: Error check */ + DosCreateThread (&os2_tick_tid, os2_wait_for_timer_event, 0, 0, 4096); + } } -static void cancel_tick (void) +static void moo_stop_ticker (void) { - if (os2_tick_sem) DosPostEventSem (os2_tick_sem); - os2_tick_done = 1; + if (ticker_started > 0 && --ticker_started == 0) + { + if (os2_tick_sem) DosPostEventSem (os2_tick_sem); + os2_tick_done = 1; + } } #elif defined(macintosh) @@ -2858,12 +2889,12 @@ static ProcessSerialNumber mac_psn; static pascal void timer_intr_handler (TMTask* task) { - swproc_moo (); + swproc_all_moos (); WakeUpProcess (&mac_psn); PrimeTime ((QElem*)&mac_tmtask, TMTASK_DELAY); } -static void setup_tick (void) +static void moo_start_ticker (void) { GetCurrentProcess (&mac_psn); memset (&mac_tmtask, 0, MOO_SIZEOF(mac_tmtask)); @@ -2872,7 +2903,7 @@ static void setup_tick (void) PrimeTime ((QElem*)&mac_tmtask, TMTASK_DELAY); } -static void cancel_tick (void) +static void moo_stop_ticker (void) { RmvTime ((QElem*)&mac_tmtask); /*DisposeTimerProc (mac_tmtask.tmAddr);*/ @@ -2882,58 +2913,47 @@ static void cancel_tick (void) static void arrange_process_switching (int sig) { - swproc_moo (); + swproc_all_moos (); } -static void setup_tick (void) +static moo_uint32_t ticker_started = 0; + +void moo_start_ticker (void) { - struct itimerval itv; - -#if 0 - struct sigaction act; - - memset (&act, 0, sizeof(act)); - sigemptyset (&act.sa_mask); - act.sa_handler = arrange_process_switching; - act.sa_flags = SA_RESTART; - sigaction (SIGVTALRM, &act, MOO_NULL); -#else - set_signal_handler (SIGVTALRM, arrange_process_switching, SA_RESTART); -#endif - -/*#define MOO_ITIMER_TICK 10000*/ /* microseconds. 0.01 seconds */ -#define MOO_ITIMER_TICK 20000 /* microseconds. 0.02 seconds. */ - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = MOO_ITIMER_TICK; - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = MOO_ITIMER_TICK; - setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); + if (++ticker_started == 1) + { + if (set_signal_handler(SIGVTALRM, arrange_process_switching, SA_RESTART) >= 0) + { + struct itimerval itv; + /*#define MOO_ITIMER_TICK 10000*/ /* microseconds. 0.01 seconds */ + #define MOO_ITIMER_TICK 20000 /* microseconds. 0.02 seconds. */ + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = MOO_ITIMER_TICK; + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = MOO_ITIMER_TICK; + setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); + } + } } -static void cancel_tick (void) +void moo_stop_ticker (void) { - struct itimerval itv; -#if 0 - struct sigaction act; -#endif - - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 0; - itv.it_value.tv_sec = 0; /* make setitimer() one-shot only */ - itv.it_value.tv_usec = 0; - setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); - -#if 0 - sigemptyset (&act.sa_mask); - act.sa_handler = SIG_IGN; /* ignore the signal potentially fired by the one-shot arrange above */ - act.sa_flags = 0; - sigaction (SIGVTALRM, &act, MOO_NULL); -#else - /* ignore the signal potentially fired by the one-shot arrange above - * instead of unsetting the signal handler */ - set_signal_handler (SIGVTALRM, SIG_IGN, 0); -#endif + if (ticker_started > 0 && --ticker_started == 0) + { + /* ignore the signal fired by the activated timer. + * unsetting the signal may cause the program to terminate(default action) */ + if (set_signal_handler(SIGVTALRM, SIG_IGN, 0) >= 0) + { + struct itimerval itv; + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; + itv.it_value.tv_sec = 0; /* make setitimer() one-shot only */ + itv.it_value.tv_usec = 0; + setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); + } + } } + #else # error UNSUPPORTED #endif @@ -3275,9 +3295,11 @@ static MOO_INLINE void chain (moo_t* moo) xtn_t* xtn = GET_XTN(moo); /* TODO: make this atomic */ + xtn->prev = MOO_NULL; + xtn->next = g_moo; + if (g_moo) GET_XTN(g_moo)->prev = moo; else g_moo = moo; - xtn->next = g_moo; /* TODO: make this atomic */ } @@ -3369,12 +3391,11 @@ void moo_abortstd (moo_t* moo) moo_abort (moo); } -int moo_compilestd(moo_t* moo, const moo_iostd_t* in, moo_oow_t count) +int moo_compilestd (moo_t* moo, const moo_iostd_t* in, moo_oow_t count) { - xtn_t* xtn; + xtn_t* xtn = GET_XTN(moo); moo_oow_t i; - xtn = GET_XTN(moo); for (i = 0; i < count; i++) { xtn->in = &in[i]; @@ -3383,3 +3404,9 @@ int moo_compilestd(moo_t* moo, const moo_iostd_t* in, moo_oow_t count) return 0; }; + +void moo_rcvtickstd (moo_t* moo, int v) +{ + xtn_t* xtn = GET_XTN(moo); + xtn->rcv_tick = v; +} diff --git a/moo/mod/Makefile.in b/moo/mod/Makefile.in index 721f361..ded4eec 100644 --- a/moo/mod/Makefile.in +++ b/moo/mod/Makefile.in @@ -419,6 +419,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@