@@ -93,7 +93,7 @@ static bool gCancelRender = false;
9393// for handling asynchronous (external) signals
9494static int gSignalNumber = 0 ;
9595static std::mutex gSignalMutex ;
96- static bool gTerminateSignalHandler = false ;
96+ static volatile bool gTerminateSignalHandler = false ;
9797
9898
9999// TODO FIXME - This way to handle signals seems rather wonky, as it is subject
@@ -114,9 +114,13 @@ static void SignalHandler (void)
114114 while (!gTerminateSignalHandler )
115115 {
116116 // Wait till a signal is caught.
117+ #ifdef HAVE_SIGTIMEDWAIT
117118 signum = sigtimedwait (&sigset, nullptr , &timeout);
118119 if (signum == -1 )
119120 continue ; // Error. Presumably timed out; check whether to end the task.
121+ #else
122+ (void )sigwait (&sigset, &signum);
123+ #endif
120124
121125 // Got a signal.
122126 std::lock_guard<std::mutex> lock (gSignalMutex );
@@ -423,6 +427,25 @@ static void CleanupBenchmark(vfeUnixSession *session, std::string& ini, std::str
423427 session->DeleteTemporaryFile (SysToUCS2String (pov.c_str ()));
424428}
425429
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+
426449int main (int argc, char **argv)
427450{
428451 vfeUnixSession *session;
@@ -499,8 +522,7 @@ int main (int argc, char **argv)
499522 PrintStatus (session) ;
500523 // TODO: general usage display (not yet in core code)
501524 session->GetUnixOptions ()->PrintOptions ();
502- gTerminateSignalHandler = true ;
503- sigthread->join ();
525+ TerminateSignalHandler (sigthread);
504526 delete sigthread;
505527 delete session;
506528 return RETURN_OK;
@@ -509,8 +531,7 @@ int main (int argc, char **argv)
509531 {
510532 session->Shutdown () ;
511533 PrintVersion ();
512- gTerminateSignalHandler = true ;
513- sigthread->join ();
534+ TerminateSignalHandler (sigthread);
514535 delete sigthread;
515536 delete session;
516537 return RETURN_OK;
@@ -519,8 +540,7 @@ int main (int argc, char **argv)
519540 {
520541 session->Shutdown ();
521542 PrintGeneration ();
522- gTerminateSignalHandler = true ;
523- sigthread->join ();
543+ TerminateSignalHandler (sigthread);
524544 delete sigthread;
525545 delete session;
526546 return RETURN_OK;
@@ -533,8 +553,7 @@ int main (int argc, char **argv)
533553 else
534554 {
535555 session->Shutdown ();
536- gTerminateSignalHandler = true ;
537- sigthread->join ();
556+ TerminateSignalHandler (sigthread);
538557 delete sigthread;
539558 delete session;
540559 return retval;
@@ -578,7 +597,7 @@ int main (int argc, char **argv)
578597 session->PauseWhenDone (true );
579598
580599 // main render loop
581- session->SetEventMask (stBackendStateChanged); // immediatly notify this event
600+ session->SetEventMask (stBackendStateChanged); // immediately notify this event
582601 while (((flags = session->GetStatus (true , 200 )) & stRenderShutdown) == 0 )
583602 {
584603 ProcessSignal ();
@@ -635,8 +654,7 @@ int main (int argc, char **argv)
635654 retval = gCancelRender ? RETURN_USER_ABORT : RETURN_ERROR;
636655 session->Shutdown ();
637656 PrintStatus (session);
638- gTerminateSignalHandler = true ;
639- sigthread->join ();
657+ TerminateSignalHandler (sigthread);
640658 delete sigthread;
641659 delete session;
642660
0 commit comments