Fix interrupt handling
This commit is contained in:
		
							parent
							
								
									951357e5fb
								
							
						
					
					
						commit
						83ae6503e8
					
				
					 4 changed files with 41 additions and 13 deletions
				
			
		|  | @ -97,6 +97,9 @@ static void opensslLockCallback(int mode, int type, const char * file, int line) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void sigHandler(int signo) { } | ||||
| 
 | ||||
| 
 | ||||
| void initNix() | ||||
| { | ||||
|     /* Turn on buffering for cerr. */ | ||||
|  | @ -130,6 +133,10 @@ void initNix() | |||
|     if (sigaction(SIGCHLD, &act, 0)) | ||||
|         throw SysError("resetting SIGCHLD"); | ||||
| 
 | ||||
|     /* Install a dummy SIGUSR1 handler for use with pthread_kill(). */ | ||||
|     act.sa_handler = sigHandler; | ||||
|     if (sigaction(SIGUSR1, &act, 0)) throw SysError("handling SIGUSR1"); | ||||
| 
 | ||||
|     /* Register a SIGSEGV handler to detect stack overflows. */ | ||||
|     detectStackOverflow(); | ||||
| 
 | ||||
|  | @ -253,6 +260,8 @@ void showManPage(const string & name) | |||
| 
 | ||||
| int handleExceptions(const string & programName, std::function<void()> fun) | ||||
| { | ||||
|     ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this
 | ||||
| 
 | ||||
|     string error = ANSI_RED "error:" ANSI_NORMAL " "; | ||||
|     try { | ||||
|         try { | ||||
|  |  | |||
|  | @ -27,8 +27,7 @@ public: | |||
|             fds[0].events = 0; | ||||
|             if (poll(fds, 1, -1) == -1) abort(); // can't happen
 | ||||
|             assert(fds[0].revents & POLLHUP); | ||||
|             /* We got POLLHUP, so send an INT signal to the main thread. */ | ||||
|             kill(getpid(), SIGINT); | ||||
|             triggerInterrupt(); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1197,7 +1197,13 @@ static void signalHandlerThread(sigset_t set) | |||
|         int signal = 0; | ||||
|         sigwait(&set, &signal); | ||||
| 
 | ||||
|         if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP) { | ||||
|         if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP) | ||||
|             triggerInterrupt(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void triggerInterrupt() | ||||
| { | ||||
|     _isInterrupted = 1; | ||||
| 
 | ||||
|     { | ||||
|  | @ -1211,8 +1217,6 @@ static void signalHandlerThread(sigset_t set) | |||
|         } | ||||
|     } | ||||
| } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void startSignalHandlerThread() | ||||
| { | ||||
|  |  | |||
|  | @ -433,5 +433,21 @@ struct InterruptCallback | |||
| std::unique_ptr<InterruptCallback> createInterruptCallback( | ||||
|     std::function<void()> callback); | ||||
| 
 | ||||
| void triggerInterrupt(); | ||||
| 
 | ||||
| /* A RAII class that causes the current thread to receive SIGUSR1 when
 | ||||
|    the signal handler thread receives SIGINT. That is, this allows | ||||
|    SIGINT to be multiplexed to multiple threads. */ | ||||
| struct ReceiveInterrupts | ||||
| { | ||||
|     pthread_t target; | ||||
|     std::unique_ptr<InterruptCallback> callback; | ||||
| 
 | ||||
|     ReceiveInterrupts() | ||||
|         : target(pthread_self()) | ||||
|         , callback(createInterruptCallback([&]() { pthread_kill(target, SIGUSR1); })) | ||||
|     { } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue