]> sigrok.org Git - libsigrok.git/commitdiff
session: Do not expect meaningful errno on non-UNIX
authorDaniel Elstner <redacted>
Sun, 30 Aug 2015 13:25:33 +0000 (15:25 +0200)
committerDaniel Elstner <redacted>
Thu, 3 Sep 2015 17:37:09 +0000 (19:37 +0200)
Looking at the g_poll() implementations for various systems, it
appears that on Windows the return value is 0 if the wait was
interrupted, and errno is never set. Also, the MacOS X wrapper
around select() does not clear revents on timeout.

To deal with these issues, check for EINTR only on Unices, and
assume revents to be invalid unless g_poll() returned a positive
value.

src/session.c

index 1e1a0a0d7020ecb28fdf71fa911a35cde6dcf342..138f4222263ebc6b1027df1b92348144429951d4 100644 (file)
@@ -396,8 +396,11 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
 {
        unsigned int i;
        int ret, timeout;
+       int revents;
        gboolean stop_checked;
        gboolean stopped;
+       struct source *source;
+       GPollFD *pollfd;
 #ifdef HAVE_LIBUSB_1_0
        int usb_timeout;
        struct timeval tv;
@@ -420,26 +423,35 @@ static int sr_session_iteration(struct sr_session *session, gboolean block)
 #endif
 
        ret = g_poll(session->pollfds, session->num_sources, timeout);
+#ifdef G_OS_UNIX
        if (ret < 0 && errno != EINTR) {
                sr_err("Error in poll: %s", g_strerror(errno));
                return SR_ERR;
        }
+#else
+       if (ret < 0) {
+               sr_err("Error in poll: %d", ret);
+               return SR_ERR;
+       }
+#endif
        stop_checked = FALSE;
        stopped = FALSE;
 
        for (i = 0; i < session->num_sources; i++) {
-               if ((ret > 0 && session->pollfds[i].revents > 0) || (ret == 0
-                       && session->source_timeout == session->sources[i].timeout)) {
+               source = &session->sources[i];
+               pollfd = &session->pollfds[i];
+               revents = (ret > 0) ? pollfd->revents : 0;
+
+               if (revents > 0 || (ret == 0
+                       && session->source_timeout == source->timeout)) {
                        /*
                         * Invoke the source's callback on an event,
                         * or if the poll timed out and this source
                         * asked for that timeout.
                         */
-                       if (!session->sources[i].cb(session->pollfds[i].fd,
-                                       session->pollfds[i].revents,
-                                       session->sources[i].cb_data))
+                       if (!source->cb(pollfd->fd, revents, source->cb_data))
                                sr_session_source_remove(session,
-                                               session->sources[i].poll_object);
+                                               source->poll_object);
                        /*
                         * We want to take as little time as possible to stop
                         * the session if we have been told to do so. Therefore,