From a583dc1cbb545a64d8c5099c221b103ea1283621 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 30 Apr 2025 12:00:38 +0800 Subject: [PATCH 1/3] optimize and cleanup the timer module to fix the bad update of tick counter --- src/include/internals.h | 2 +- src/include/timer.h | 2 +- src/kernel/desktop-ths.c | 2 +- src/kernel/timer.c | 233 ++++++++------------------------------- 4 files changed, 50 insertions(+), 189 deletions(-) diff --git a/src/include/internals.h b/src/include/internals.h index 0c7079e6..f9dc9b63 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -258,7 +258,7 @@ struct _MSGQUEUE int loop_depth; // message loop depth, for dialog boxes int idle_counter; // the idle connter for MSG_IDLE - DWORD last_ticks_desktop; // the last tick count for desktop timer + DWORD last_ticks; // the last tick count saved; since 5.0.14 /* Since 5.0.0, MiniGUI provides support for timers per message thread */ int nr_timers; // the number of active timers diff --git a/src/include/timer.h b/src/include/timer.h index 4978cc8b..f2f7a9ee 100644 --- a/src/include/timer.h +++ b/src/include/timer.h @@ -74,7 +74,7 @@ typedef struct _MSGQUEUE MSGQUEUE; extern "C" { #endif /* __cplusplus */ -void __mg_update_tick_count (void* data); +DWORD __mg_update_tick_count (MSGQUEUE* msg_queue); int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter); void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue); void __mg_remove_timer (MSGQUEUE* msg_queue, int slot); diff --git a/src/kernel/desktop-ths.c b/src/kernel/desktop-ths.c index 402714b7..b79d09ac 100644 --- a/src/kernel/desktop-ths.c +++ b/src/kernel/desktop-ths.c @@ -145,7 +145,7 @@ static IDLEHANDLER std_idle_handler; static BOOL idle_handler_for_desktop_thread (MSGQUEUE *msg_queue, BOOL wait) { - __mg_update_tick_count (NULL); + __mg_update_tick_count (msg_queue); return std_idle_handler (msg_queue, wait); } diff --git a/src/kernel/timer.c b/src/kernel/timer.c index ff895c90..93f49fe4 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -44,7 +44,7 @@ * . */ /* -** timer.c: The Timer module for MiniGUI-Threads. +** timer.c: The Timer module for MiniGUI. ** ** Current maintainer: Wei Yongming. ** @@ -79,139 +79,44 @@ DWORD __mg_tick_counter = 0; -/* update timer count for desktop thread */ -void __mg_update_tick_count (void *data) +/* update timer count for message and desktop thread */ +DWORD __mg_update_tick_count (MSGQUEUE* msg_queue) { + DWORD ticks; + #if defined(_MGRM_PROCESSES) if (mgIsServer) { - __mg_tick_counter = __mg_os_get_time_ticks (); - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; + ticks = __mg_os_get_time_ticks (); + SHAREDRES_TIMER_COUNTER = ticks; } else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; + ticks = SHAREDRES_TIMER_COUNTER; } #else /* defined _MGRM_PROCESSES */ - __mg_tick_counter = __mg_os_get_time_ticks (); + ticks = __mg_os_get_time_ticks (); #endif /* not defined _MGRM_PROCESSES */ - /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT - message, and the interval for the timer of desktop changes to 0.05s. */ - if (__mg_tick_counter > - __mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) { - __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; + if (msg_queue && ticks != msg_queue->last_ticks) { + /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT + message, and the interval for the timer of desktop changes to 0.05s. + */ + if (msg_queue == __mg_dsk_msg_queue) { + if (ticks > __mg_dsk_msg_queue->last_ticks + + DESKTOP_TIMER_INERTVAL) { + __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; #ifdef _MGRM_THREADS /* only wake up desktop for threads mode */ - POST_MSGQ (__mg_dsk_msg_queue); + POST_MSGQ (__mg_dsk_msg_queue); #endif - __mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter; + } + } + + msg_queue->last_ticks = ticks; } -#if 0 /* deprecated code */ -#if defined(_MGRM_PROCESSES) - if (mgIsServer) { - DWORD elapsed_ticks; - - /* Since 5.0.0, we use elapsed time in ms to count the ticks */ - elapsed_ticks = __mg_os_get_elapsed_ms (); - elapsed_ticks = (elapsed_ticks + 5) / 10; - - __mg_tick_counter += elapsed_ticks; - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; - } - else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; - } -#else /* defined _MGRM_PROCESSES */ - DWORD elapsed_ticks; - - /* Since 5.0.0, we use elapsed time in ms to count the ticks */ - elapsed_ticks = __mg_os_get_elapsed_ms (); - elapsed_ticks = (elapsed_ticks + 5) / 10; - __mg_tick_counter += elapsed_ticks; -#endif /* not defined _MGRM_PROCESSES */ - - /* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT - message, and the interval for the timer of desktop changes to 0.05s. */ - if (__mg_tick_counter > - __mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) { - __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; -#ifdef _MGRM_THREADS /* only wake up desktop for threads mode */ - POST_MSGQ (__mg_dsk_msg_queue); -#endif - __mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter; - } -#endif /* deprecated code */ + __mg_tick_counter = ticks; + return ticks; } -#ifdef __NOUNIX__ - -static BOOL install_system_timer (void) -{ - return TRUE; -} - -static BOOL unintall_system_timer (void) -{ - return TRUE; -} - -#else /* defined __NOUNIX__ */ - -#include -#include -#include - -static struct sigaction old_alarm_handler; -static struct itimerval old_timer; - -static BOOL install_system_timer (void) -{ - struct itimerval timerv; - struct sigaction siga; - - sigaction (SIGALRM, NULL, &old_alarm_handler); - - siga = old_alarm_handler; - siga.sa_handler = (void(*)(int))__mg_update_tick_count; -#ifndef _MGRM_STANDALONE - siga.sa_flags = 0; -#else - siga.sa_flags = SA_RESTART; -#endif - sigaction (SIGALRM, &siga, NULL); - - timerv.it_interval.tv_sec = 0; -#if defined(__uClinux__) && defined(_MGRM_STANDALONE) - timerv.it_interval.tv_usec = 100000; /* 100 ms */ -#else - timerv.it_interval.tv_usec = 10000; /* 10 ms */ -#endif - timerv.it_value = timerv.it_interval; - - if (setitimer (ITIMER_REAL, &timerv, &old_timer) == -1) { - TIMER_ERR_SYS ("setitimer call failed!\n"); - return FALSE; - } - - return TRUE; -} - -static BOOL unintall_system_timer (void) -{ - if (setitimer (ITIMER_REAL, &old_timer, 0) == -1) { - TIMER_ERR_SYS ("setitimer call failed!\n"); - return FALSE; - } - - if (sigaction (SIGALRM, &old_alarm_handler, NULL) == -1) { - TIMER_ERR_SYS ("sigaction call failed!\n"); - return FALSE; - } - - return TRUE; -} - -#endif /* not defined __NOUNIX__ */ - BOOL mg_InitTimer (BOOL use_sys_timer) { __mg_tick_counter = 0; @@ -219,7 +124,8 @@ BOOL mg_InitTimer (BOOL use_sys_timer) __mg_os_start_time(); if (use_sys_timer) { - install_system_timer (); + // Since 5.0.14, do nothing. + // install_system_timer (); } return TRUE; @@ -227,8 +133,10 @@ BOOL mg_InitTimer (BOOL use_sys_timer) void mg_TerminateTimer (BOOL use_sys_timer) { - if (use_sys_timer) - unintall_system_timer (); + if (use_sys_timer) { + // Since 5.0.14, do nothing. + // unintall_system_timer (); + } } /************************* Functions run in message thread *******************/ @@ -247,34 +155,21 @@ int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter) int i; TIMER** timer_slots = msg_queue->timer_slots; + __mg_update_tick_count (msg_queue); + for (i = 0; i < DEF_NR_TIMERS; i++) { if (timer_slots[i]) { - if (__mg_tick_counter >= timer_slots[i]->ticks_expected) { + if (msg_queue->last_ticks >= timer_slots[i]->ticks_expected) { /* setting timer flag is simple, we do not need to lock msgq, or else we may encounter dead lock here */ msg_queue->expired_timer_mask |= (0x01UL << i); POST_MSGQ (msg_queue); - timer_slots[i]->ticks_expected += timer_slots[i]->interv; - timer_slots[i]->ticks_fired = __mg_tick_counter; + timer_slots[i]->ticks_expected = + msg_queue->last_ticks + timer_slots[i]->interv; + timer_slots[i]->ticks_fired = msg_queue->last_ticks; nr++; } -#if 0 /* deprecated code */ - timer_slots[i]->count += inter; - if (timer_slots[i]->count >= timer_slots[i]->interv) { -#ifdef _MGRM_PROCESSES - timer_slots[i]->ticks_current = SHAREDRES_TIMER_COUNTER; -#else - timer_slots[i]->ticks_current = __mg_tick_counter; -#endif - /* setting timer flag is simple, we do not need to lock msgq, - or else we may encounter dead lock here */ - msg_queue->expired_timer_mask |= (0x01UL << i); - POST_MSGQ (msg_queue); - timer_slots[i]->count -= timer_slots[i]->interv; - nr++; - } -#endif /* deprecated code */ } } } @@ -291,12 +186,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, int i; int slot = -1; TIMER** timer_slots; - PMSGQUEUE pMsgQueue; - -#ifndef _MGRM_THREADS - /* Force to update tick count */ - GetTickCount(); -#endif + PMSGQUEUE msg_queue; if (id == 0) { _WRN_PRINTF ("bad identifier (%ld).\n", id); @@ -307,12 +197,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, interv = 1; } - timer_slots = getTimerSlotsForThisThread (&pMsgQueue); + timer_slots = getTimerSlotsForThisThread (&msg_queue); if (MG_UNLIKELY (timer_slots == NULL)) { _WRN_PRINTF ("called for non message thread\n"); goto badret; } + __mg_update_tick_count (msg_queue); + /* Since 5.0.0: only check hWnd if timer_proc is NULL */ if (MG_UNLIKELY (timer_proc == NULL && !getMainWinIfWindowInThisThread (hWnd))) { @@ -331,7 +223,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, /* Since 5.0.0: we reset timer parameters for duplicated call of this function */ timer_slots[i]->interv = interv; - timer_slots[i]->ticks_expected = __mg_tick_counter + interv; + timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[i]->ticks_fired = 0; timer_slots[i]->proc = timer_proc; return TRUE; @@ -348,14 +240,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv, timer_slots[slot]->hWnd = hWnd; timer_slots[slot]->id = id; timer_slots[slot]->interv = interv; - timer_slots[slot]->ticks_expected = __mg_tick_counter + interv; + timer_slots[slot]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[slot]->ticks_fired = 0; timer_slots[slot]->proc = timer_proc; _DBG_PRINTF ("ticks_expected (%d): %lu, tick_counter: %lu\n", - slot, timer_slots[slot]->ticks_expected, __mg_tick_counter); + slot, timer_slots[slot]->ticks_expected, msg_queue->last_ticks); - pMsgQueue->nr_timers++; + msg_queue->nr_timers++; return TRUE; @@ -363,24 +255,6 @@ badret: return FALSE; } -#if 0 /* deprected code */ -#ifdef _MGRM_PROCESSES -static void reset_select_timeout (TIMER** timer_slots) -{ - int i; - - unsigned int interv = 0; - for (i = 0; i < DEF_NR_TIMERS; i++) { - if (timer_slots[i]) { - if (interv == 0 || timer_slots[i]->interv < interv) - interv = timer_slots[i]->interv; - } - } - __mg_set_select_timeout (USEC_10MS * interv); -} -#endif -#endif /* deprecated code */ - void __mg_remove_timer (MSGQUEUE* msg_queue, int slot) { TIMER** timer_slots; @@ -470,13 +344,14 @@ BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD interv, if (MG_LIKELY (msg_queue)) { TIMER** timer_slots = msg_queue->timer_slots; + __mg_update_tick_count (msg_queue); for (i = 0; i < DEF_NR_TIMERS; i++) { if (timer_slots[i] && timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) { /* Should clear old timer flags */ msg_queue->expired_timer_mask &= ~(0x01UL << i); timer_slots[i]->interv = interv; - timer_slots[i]->ticks_expected = __mg_tick_counter + interv; + timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv; timer_slots[i]->ticks_fired = 0; if (timer_proc != (TIMERPROC)INV_PTR) timer_slots[i]->proc = timer_proc; @@ -548,20 +423,6 @@ BOOL GUIAPI HaveFreeTimer (void) DWORD GUIAPI GetTickCount (void) { -#if defined(_MGRM_PROCESSES) - if (mgIsServer) { - __mg_tick_counter = __mg_os_get_time_ticks (); - SHAREDRES_TIMER_COUNTER = __mg_tick_counter; - } - else { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; - } -#elif defined(_MGRM_STANDALONE) - __mg_tick_counter = __mg_os_get_time_ticks (); -#else /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */ - /* do nothing here because the desktop thread updates the tick count */ -#endif /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */ - - return __mg_tick_counter; + return __mg_update_tick_count(getMsgQueueForThisThread ()); } From 3ef2340749eafb58e90ceafa347b89225cfc39c7 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 30 Apr 2025 12:10:47 +0800 Subject: [PATCH 2/3] restore old logic to update timer_expected --- src/kernel/timer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/kernel/timer.c b/src/kernel/timer.c index 93f49fe4..09c9db0b 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -164,9 +164,7 @@ int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter) msgq, or else we may encounter dead lock here */ msg_queue->expired_timer_mask |= (0x01UL << i); POST_MSGQ (msg_queue); - - timer_slots[i]->ticks_expected = - msg_queue->last_ticks + timer_slots[i]->interv; + timer_slots[i]->ticks_expected += timer_slots[i]->interv; timer_slots[i]->ticks_fired = msg_queue->last_ticks; nr++; } From 3643606a7f3830696ebb585727e0742553282a0e Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 30 Apr 2025 14:12:19 +0800 Subject: [PATCH 3/3] restore the system interval timer for the server under runmode procs --- src/include/internals.h | 37 ++---------------- src/kernel/init.c | 4 +- src/kernel/timer.c | 77 ++++++++++++++++++++++++++++++++----- src/server/server.c | 26 +------------ src/standalone/standalone.c | 4 +- 5 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/include/internals.h b/src/include/internals.h index f9dc9b63..37839a84 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -911,40 +911,9 @@ static inline MSGQUEUE* getMsgQueueIfMainWindowInThisThread (PMAINWIN pMainWin) #endif /* defined _MGHAVE_VIRTUAL_WINDOW */ -#if 0 /* deprecated code */ -/* since 5.0.0, we always use QS_DESKTIMER for desktop timer */ -/* since 5.0.0, we no longer use the timer thread */ -static inline void AlertDesktopTimerEvent (void) -{ - if (__mg_dsk_msg_queue) { - __mg_dsk_msg_queue->expired_timer_mask = 1; - POST_MSGQ (__mg_dsk_msg_queue); - } -} - -static inline void AlertDesktopTimerEvent (void) -{ - __mg_dsk_msg_queue->dwState |= QS_DESKTIMER; -#ifdef _MGHAVE_VIRTUAL_WINDOW - if (getMsgQueueForThisThread() != __mg_dsk_msg_queue) - POST_MSGQ (__mg_dsk_msg_queue); -#endif /* defined _MGHAVE_VIRTUAL_WINDOW */ -} - -static inline void setMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) -{ - pMsgQueue->expired_timer_mask |= (0x01UL << slot); - POST_MSGQ (pMsgQueue); -} - -static inline void removeMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot) -{ - pMsgQueue->expired_timer_mask &= ~(0x01UL << slot); -} -#endif /* deprecated code */ - -BOOL mg_InitTimer (BOOL use_sys_timer); -void mg_TerminateTimer (BOOL use_sys_timer); +/* Since 5.0.14, remove arg use_sys_timer */ +BOOL mg_InitTimer (void); +void mg_TerminateTimer (void); /*window element renderer manager interface*/ extern WINDOW_ELEMENT_RENDERER * __mg_def_renderer; diff --git a/src/kernel/init.c b/src/kernel/init.c index f6a822ea..6f189957 100644 --- a/src/kernel/init.c +++ b/src/kernel/init.c @@ -577,7 +577,7 @@ int GUIAPI InitGUI (int args, const char *agr[]) /* init timer for tick counter */ step++; - if (!mg_InitTimer (FALSE)) { + if (!mg_InitTimer()) { _ERR_PRINTF ("KERNEL>InitGUI: failed to start time counter\n"); goto failure; } @@ -602,7 +602,7 @@ failure1: void GUIAPI TerminateGUI (int not_used) { - mg_TerminateTimer (FALSE); + mg_TerminateTimer (); mg_FreeMsgQueueForThisThread (TRUE); diff --git a/src/kernel/timer.c b/src/kernel/timer.c index 09c9db0b..7fd1ab75 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -117,26 +117,83 @@ DWORD __mg_update_tick_count (MSGQUEUE* msg_queue) return ticks; } -BOOL mg_InitTimer (BOOL use_sys_timer) +#if defined(_MGRM_PROCESSES) + +#include +#include +#include + +static struct sigaction old_alarm_handler; +static struct itimerval old_timer; + +static void timer_handler(int sig) { - __mg_tick_counter = 0; + (void)sig; + __mg_update_tick_count(NULL); +} - __mg_os_start_time(); +static BOOL install_system_timer (void) +{ + struct itimerval timerv; + struct sigaction siga; - if (use_sys_timer) { - // Since 5.0.14, do nothing. - // install_system_timer (); + sigaction (SIGALRM, NULL, &old_alarm_handler); + + siga = old_alarm_handler; + siga.sa_handler = timer_handler; + siga.sa_flags = 0; + sigaction (SIGALRM, &siga, NULL); + + timerv.it_interval.tv_sec = 0; + timerv.it_interval.tv_usec = 10000; /* 10 ms */ + timerv.it_value = timerv.it_interval; + + if (setitimer (ITIMER_REAL, &timerv, &old_timer) == -1) { + TIMER_ERR_SYS ("setitimer call failed!\n"); + return FALSE; } return TRUE; } -void mg_TerminateTimer (BOOL use_sys_timer) +static BOOL unintall_system_timer (void) { - if (use_sys_timer) { - // Since 5.0.14, do nothing. - // unintall_system_timer (); + if (setitimer (ITIMER_REAL, &old_timer, 0) == -1) { + TIMER_ERR_SYS ("setitimer call failed!\n"); + return FALSE; } + + if (sigaction (SIGALRM, &old_alarm_handler, NULL) == -1) { + TIMER_ERR_SYS ("sigaction call failed!\n"); + return FALSE; + } + + return TRUE; +} +#endif /* defined(_MGRM_PROCESSES) */ + +BOOL mg_InitTimer () +{ + __mg_tick_counter = 0; + + __mg_os_start_time(); + +#if defined(_MGRM_PROCESSES) + if (mgIsServer) { + install_system_timer (); + } +#endif + + return TRUE; +} + +void mg_TerminateTimer (void) +{ +#if defined(_MGRM_PROCESSES) + if (mgIsServer) { + unintall_system_timer (); + } +#endif } /************************* Functions run in message thread *******************/ diff --git a/src/server/server.c b/src/server/server.c index 58c88e03..0dc031d3 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -84,20 +84,6 @@ extern DWORD __mg_tick_counter; ON_NEW_DEL_CLIENT OnNewDelClient = NULL; -#if 0 -/* Since 5.0.0, use RegisterEventHookFunc to implement SetServerEventHook */ -static SRVEVTHOOK srv_evt_hook = NULL; - -SRVEVTHOOK GUIAPI SetServerEventHook (SRVEVTHOOK SrvEvtHook) -{ - SRVEVTHOOK old_hook = srv_evt_hook; - - srv_evt_hook = SrvEvtHook; - - return old_hook; -} -#endif /* deprecated code; moved to window.c */ - static void ParseEvent (PMSGQUEUE msg_que, int event) { LWEVENT lwe; @@ -323,7 +309,7 @@ BOOL GUIAPI ServerStartup (int nr_globals, __mg_dsk_msg_queue->maxfd = listenfd; maxi = -1; - mg_InitTimer (TRUE); + mg_InitTimer (); __mg_start_server_desktop (); @@ -347,7 +333,7 @@ void server_ServerCleanup (void) { __mg_cleanup_layers (); - mg_TerminateTimer (TRUE); + mg_TerminateTimer (); unlink (CS_PATH); } @@ -365,14 +351,6 @@ BOOL server_IdleHandler4Server (PMSGQUEUE msg_queue, BOOL wait) EXTRA_INPUT_EVENT extra; // Since 4.0.0; for extra input events int nevts = 0; // Since 5.0.0; for timer and fd events -#if 0 /* deprecated code */ - /* since 5.0.0, use __mg_update_tick_count instead */ - if (__mg_tick_counter != SHAREDRES_TIMER_COUNTER) { - __mg_tick_counter = SHAREDRES_TIMER_COUNTER; - AlertDesktopTimerEvent (); - } -#endif /* deprecated code */ - /* rset gets modified each time around */ rset = __mg_dsk_msg_queue->rfdset; if (__mg_dsk_msg_queue->nr_wfds) { diff --git a/src/standalone/standalone.c b/src/standalone/standalone.c index dab0a63f..f0ce697f 100644 --- a/src/standalone/standalone.c +++ b/src/standalone/standalone.c @@ -190,14 +190,14 @@ static void ParseEvent (PMSGQUEUE msg_que, int event) BOOL GUIAPI salone_StandAloneStartup (void) { /* VW: do not use signal based interval timer; since 4.0 */ - mg_InitTimer (FALSE); + mg_InitTimer (); return TRUE; } void salone_StandAloneCleanup (void) { /* VW: do not use signal based interval timer; since 4.0 */ - mg_TerminateTimer (FALSE); + mg_TerminateTimer (); } BOOL salone_IdleHandler4StandAlone (PMSGQUEUE msg_queue, BOOL wait)