c - How to handle SIGPIPE in a multithreaded environment?
c, linux, multithreading, signals
Solution
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).
Problem
I have a multithreaded SSL server written in C, whose behavior is as follows: - Main thread waits for client requests (`epoll`), accepts them and spawns a detached thread for each client socket - Each thread does `SSL_accept` separately. After successful SSL handshake, the thread receives messages from the client and responds back with a message for each `SSL_read`. - Client threads exit when clients close socket or any error occurs. 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.