mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-15 22:04:44 +00:00
fix initialization of timer thread that could be put in indefinite suspended
state from the start.
This commit is contained in:
parent
cd31ea2d80
commit
260614a873
@ -70,7 +70,8 @@ static int32 timer_func(void *arg);
|
|||||||
#endif
|
#endif
|
||||||
#ifdef PRECISE_TIMING_POSIX
|
#ifdef PRECISE_TIMING_POSIX
|
||||||
static pthread_t timer_thread;
|
static pthread_t timer_thread;
|
||||||
static volatile bool thread_active = false;
|
static bool timer_thread_active = false;
|
||||||
|
static volatile bool timer_thread_cancel = false;
|
||||||
static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
|
static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
|
||||||
static tm_time_t wakeup_time = wakeup_time_max;
|
static tm_time_t wakeup_time = wakeup_time_max;
|
||||||
static sem_t wakeup_time_sem;
|
static sem_t wakeup_time_sem;
|
||||||
@ -165,16 +166,13 @@ static struct sigaction sigresume_action;
|
|||||||
static int suspend_count = 0;
|
static int suspend_count = 0;
|
||||||
static pthread_mutex_t suspend_count_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t suspend_count_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static sem_t suspend_ack_sem;
|
static sem_t suspend_ack_sem;
|
||||||
|
static sigset_t suspend_handler_mask;
|
||||||
|
|
||||||
// Signal handler for suspended thread
|
// Signal handler for suspended thread
|
||||||
static void sigsuspend_handler(int sig)
|
static void sigsuspend_handler(int sig)
|
||||||
{
|
{
|
||||||
sem_post(&suspend_ack_sem);
|
sem_post(&suspend_ack_sem);
|
||||||
|
sigsuspend(&suspend_handler_mask);
|
||||||
sigset_t mask;
|
|
||||||
sigfillset(&mask);
|
|
||||||
sigdelset(&mask, SIGRESUME);
|
|
||||||
sigsuspend(&mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal handler for resumed thread
|
// Signal handler for resumed thread
|
||||||
@ -210,6 +208,12 @@ static bool timer_thread_init(void)
|
|||||||
if (sem_init(&suspend_ack_sem, 0, 0) < 0)
|
if (sem_init(&suspend_ack_sem, 0, 0) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Initialize suspend_handler_mask, it excludes SIGRESUME
|
||||||
|
if (sigfillset(&suspend_handler_mask) != 0)
|
||||||
|
return false;
|
||||||
|
if (sigdelset(&suspend_handler_mask, SIGRESUME) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Create thread in running state
|
// Create thread in running state
|
||||||
suspend_count = 0;
|
suspend_count = 0;
|
||||||
return (pthread_create(&timer_thread, NULL, timer_func, NULL) == 0);
|
return (pthread_create(&timer_thread, NULL, timer_func, NULL) == 0);
|
||||||
@ -218,6 +222,7 @@ static bool timer_thread_init(void)
|
|||||||
// Kill timer thread
|
// Kill timer thread
|
||||||
static void timer_thread_kill(void)
|
static void timer_thread_kill(void)
|
||||||
{
|
{
|
||||||
|
timer_thread_cancel = true;
|
||||||
#ifdef HAVE_PTHREAD_CANCEL
|
#ifdef HAVE_PTHREAD_CANCEL
|
||||||
pthread_cancel(timer_thread);
|
pthread_cancel(timer_thread);
|
||||||
#endif
|
#endif
|
||||||
@ -269,7 +274,7 @@ void TimerInit(void)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef PRECISE_TIMING_POSIX
|
#ifdef PRECISE_TIMING_POSIX
|
||||||
sem_init(&wakeup_time_sem, 0, 1);
|
sem_init(&wakeup_time_sem, 0, 1);
|
||||||
thread_active = timer_thread_init();
|
timer_thread_active = timer_thread_init();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -293,7 +298,6 @@ void TimerExit(void)
|
|||||||
delete_sem(wakeup_time_sem);
|
delete_sem(wakeup_time_sem);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PRECISE_TIMING_POSIX
|
#ifdef PRECISE_TIMING_POSIX
|
||||||
thread_active = false;
|
|
||||||
timer_thread_kill();
|
timer_thread_kill();
|
||||||
sem_destroy(&wakeup_time_sem);
|
sem_destroy(&wakeup_time_sem);
|
||||||
#endif
|
#endif
|
||||||
@ -522,7 +526,7 @@ static int32 timer_func(void *arg)
|
|||||||
#ifdef PRECISE_TIMING_POSIX
|
#ifdef PRECISE_TIMING_POSIX
|
||||||
static void *timer_func(void *arg)
|
static void *timer_func(void *arg)
|
||||||
{
|
{
|
||||||
while (thread_active) {
|
while (!timer_thread_cancel) {
|
||||||
|
|
||||||
// Wait until time specified by wakeup_time
|
// Wait until time specified by wakeup_time
|
||||||
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
|
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user