Cygwin: sigtimedwait workaround for SIGPIPE handling on wait pipe write
authorChristian Babeux <christian.babeux@efficios.com>
Wed, 28 Nov 2012 03:27:56 +0000 (22:27 -0500)
committerChristian Babeux <christian.babeux@efficios.com>
Wed, 28 Nov 2012 03:32:28 +0000 (22:32 -0500)
sigtimedwait(3) is not available in Cygwin. To workaround
this limitation, if a SIGPIPE is pending after a write(3),
kill ourselve with SIGPIPE and use sigwaitinfo(3) to wait
on delivery and effectively "discarding" the signal.

libringbuffer/frontend_internal.h

index 2d3b1071f9e4f10565ca52b0385c65359a8866f2..9ff28e3968e503d7d8e974064f1b3150f236088c 100644 (file)
@@ -457,11 +457,20 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config
                                                ret = write(wakeup_fd, "", 1);
                                        } while (ret == -1L && errno == EINTR);
                                        if (ret == -1L && errno == EPIPE && !sigpipe_was_pending) {
-                                               struct timespec timeout = { 0, 0 };
-                                               do {
-                                                       ret = sigtimedwait(&sigpipe_set, NULL,
-                                                               &timeout);
-                                               } while (ret == -1L && errno == EINTR);
+                                               ret = sigpending(&pending_set);
+                                               assert(!ret);
+
+                                               if (sigismember(&pending_set, SIGPIPE)) {
+                                                       /*
+                                                        * Kill ourselves with SIGPIPE and wait on
+                                                        * delivery, thus effectively discarding it.
+                                                        */
+                                                       pthread_t self = pthread_self();
+                                                       pthread_kill(self, SIGPIPE);
+                                                       do {
+                                                               ret = sigwaitinfo(&sigpipe_set, NULL);
+                                                       } while (ret == -1L && errno == EINTR);
+                                               }
                                        }
                                        if (!sigpipe_was_pending) {
                                                ret = pthread_sigmask(SIG_SETMASK, &old_set, NULL);
This page took 0.02541 seconds and 4 git commands to generate.