Reputation: 379
I have a multithreaded SSL server written in C, whose behavior is as follows:
epoll
), accepts them and spawns a detached thread for each client socketSSL_accept
separately. After successful SSL handshake, the thread receives messages from the client and responds back with a message for each SSL_read
.I tried simulating concurrent client connections to test the server.
During one such simulation, my server exited with SIGPIPE
signal.
Is there a way to catch and handle SIGPIPE
at thread level? I want the respective thread to handle the signal instead of the entire process exiting.
Initially I tried signal(SIGPIPE,SIG_IGN)
, but signal(2) man says:
The effects of signal() in a multithreaded process are unspecified.
Can signalfd be used to handle such SIGPIPEs
?
Or are there other solutions?
Note:Server runs on Ubuntu 12.04 and I can't use MSG_NOSIGNAL
on send
since I am using the OpenSSL as library directly (no source code)
Thanks in advance.
Upvotes: 4
Views: 4638
Reputation: 1723
Is there a way to catch and handle SIGPIPE at thread level? I want the respective thread to handle the signal instead of the entire process exiting.
Yes, there is. You need to block the signal in all threads except one (it would be best to do this before creating any thread). If you are using pthreads, you can use pthread_sigmask
as this will guarantee, that after calling it every created thread will inherit signal mask. Then in one specific thread you need to register a handler (don't use signal
, it's obsolete) with sigaction
.
When signal reaches your process it will be blocked until this one thread will continue it's work on process (only then the signal is received by process, that's why it's unspecified behavior - it depends on which thread is running, but by blocking signal on all other threads you specify which one can react to it).
Other way around:
If you want to not receive this signal ever ever and be aware of which socket was broken with it, you can only use pthread_sigmask
and ignore this signal for all threads. Then function, which broke because of SIGPIPE should return -1 (I'm not familiar with openssl, but when it comes to sockets, it's write
way of saying, the socket was closed on the other side).
Upvotes: 6