|
25 | 25 | /* RAII class used to ignore a signal in a scope. If sigprocmask is
|
26 | 26 | supported, then the signal is only ignored by the calling thread.
|
27 | 27 | Otherwise, the signal disposition is set to SIG_IGN, which affects
|
28 |
| - the whole process. */ |
29 |
| - |
30 |
| -template <int Sig> |
| 28 | + the whole process. If ConsumePending is true, the destructor |
| 29 | + consumes a pending Sig. SIGPIPE for example is queued on the |
| 30 | + thread even if blocked at the time the pipe is written to. SIGTTOU |
| 31 | + OTOH is not raised at all if the thread writing to the terminal has |
| 32 | + it blocked. Because SIGTTOU is sent to the whole process instead |
| 33 | + of to a specific thread, consuming a pending SIGTTOU in the |
| 34 | + destructor could consume a signal raised due to actions done by |
| 35 | + some other thread. */ |
| 36 | + |
| 37 | +template <int Sig, bool ConsumePending> |
31 | 38 | class scoped_ignore_signal
|
32 | 39 | {
|
33 | 40 | public:
|
@@ -58,7 +65,8 @@ class scoped_ignore_signal
|
58 | 65 |
|
59 | 66 | /* If we got a pending Sig signal, consume it before
|
60 | 67 | unblocking. */
|
61 |
| - sigtimedwait (&set, nullptr, &zero_timeout); |
| 68 | + if (ConsumePending) |
| 69 | + sigtimedwait (&set, nullptr, &zero_timeout); |
62 | 70 |
|
63 | 71 | sigprocmask (SIG_UNBLOCK, &set, nullptr);
|
64 | 72 | }
|
@@ -89,7 +97,7 @@ struct scoped_ignore_signal_nop
|
89 | 97 | };
|
90 | 98 |
|
91 | 99 | #ifdef SIGPIPE
|
92 |
| -using scoped_ignore_sigpipe = scoped_ignore_signal<SIGPIPE>; |
| 100 | +using scoped_ignore_sigpipe = scoped_ignore_signal<SIGPIPE, true>; |
93 | 101 | #else
|
94 | 102 | using scoped_ignore_sigpipe = scoped_ignore_signal_nop;
|
95 | 103 | #endif
|
|
0 commit comments