@@ -93,7 +93,7 @@ static bool gCancelRender = false;
93
93
// for handling asynchronous (external) signals
94
94
static int gSignalNumber = 0 ;
95
95
static std::mutex gSignalMutex ;
96
- static bool gTerminateSignalHandler = false ;
96
+ static volatile bool gTerminateSignalHandler = false ;
97
97
98
98
99
99
// TODO FIXME - This way to handle signals seems rather wonky, as it is subject
@@ -114,9 +114,13 @@ static void SignalHandler (void)
114
114
while (!gTerminateSignalHandler )
115
115
{
116
116
// Wait till a signal is caught.
117
+ #ifdef HAVE_SIGTIMEDWAIT
117
118
signum = sigtimedwait (&sigset, nullptr , &timeout);
118
119
if (signum == -1 )
119
120
continue ; // Error. Presumably timed out; check whether to end the task.
121
+ #else
122
+ (void )sigwait (&sigset, &signum);
123
+ #endif
120
124
121
125
// Got a signal.
122
126
std::lock_guard<std::mutex> lock (gSignalMutex );
@@ -423,6 +427,25 @@ static void CleanupBenchmark(vfeUnixSession *session, std::string& ini, std::str
423
427
session->DeleteTemporaryFile (SysToUCS2String (pov.c_str ()));
424
428
}
425
429
430
+ static void TerminateSignalHandler (std::thread* sigthread)
431
+ {
432
+ gTerminateSignalHandler = true ;
433
+ #ifdef HAVE_SIGTIMEDWAIT
434
+ // `std::thread`s must be `join`ed or `detach`ed before destruction,
435
+ // otherwise their destructor causes ungraceful termination of the entire
436
+ // program.
437
+ sigthread->join ();
438
+ #else
439
+ // `std::thread`s must be `join`ed or `detach`ed before destruction,
440
+ // otherwise their destructor causes ungraceful termination of the entire
441
+ // program. `join` is not an option because we can't reliably make the
442
+ // thread terminate itself, so we must trust the OS that it will kill any
443
+ // `detach`ed threads when their parent process exits.
444
+ // TODO - This is a hackish solution.
445
+ sigthread->detach ();
446
+ #endif
447
+ }
448
+
426
449
int main (int argc, char **argv)
427
450
{
428
451
vfeUnixSession *session;
@@ -499,8 +522,7 @@ int main (int argc, char **argv)
499
522
PrintStatus (session) ;
500
523
// TODO: general usage display (not yet in core code)
501
524
session->GetUnixOptions ()->PrintOptions ();
502
- gTerminateSignalHandler = true ;
503
- sigthread->join ();
525
+ TerminateSignalHandler (sigthread);
504
526
delete sigthread;
505
527
delete session;
506
528
return RETURN_OK;
@@ -509,8 +531,7 @@ int main (int argc, char **argv)
509
531
{
510
532
session->Shutdown () ;
511
533
PrintVersion ();
512
- gTerminateSignalHandler = true ;
513
- sigthread->join ();
534
+ TerminateSignalHandler (sigthread);
514
535
delete sigthread;
515
536
delete session;
516
537
return RETURN_OK;
@@ -519,8 +540,7 @@ int main (int argc, char **argv)
519
540
{
520
541
session->Shutdown ();
521
542
PrintGeneration ();
522
- gTerminateSignalHandler = true ;
523
- sigthread->join ();
543
+ TerminateSignalHandler (sigthread);
524
544
delete sigthread;
525
545
delete session;
526
546
return RETURN_OK;
@@ -533,8 +553,7 @@ int main (int argc, char **argv)
533
553
else
534
554
{
535
555
session->Shutdown ();
536
- gTerminateSignalHandler = true ;
537
- sigthread->join ();
556
+ TerminateSignalHandler (sigthread);
538
557
delete sigthread;
539
558
delete session;
540
559
return retval;
@@ -578,7 +597,7 @@ int main (int argc, char **argv)
578
597
session->PauseWhenDone (true );
579
598
580
599
// main render loop
581
- session->SetEventMask (stBackendStateChanged); // immediatly notify this event
600
+ session->SetEventMask (stBackendStateChanged); // immediately notify this event
582
601
while (((flags = session->GetStatus (true , 200 )) & stRenderShutdown) == 0 )
583
602
{
584
603
ProcessSignal ();
@@ -635,8 +654,7 @@ int main (int argc, char **argv)
635
654
retval = gCancelRender ? RETURN_USER_ABORT : RETURN_ERROR;
636
655
session->Shutdown ();
637
656
PrintStatus (session);
638
- gTerminateSignalHandler = true ;
639
- sigthread->join ();
657
+ TerminateSignalHandler (sigthread);
640
658
delete sigthread;
641
659
delete session;
642
660
0 commit comments