Add a flag for blocking read
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 1 Jul 2013 05:46:23 +0000 (15:46 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 2 Jul 2013 00:59:01 +0000 (10:59 +1000)
Not all clients need nonblocking read, so add a flag to read
in blocking mode. In that mode, events are only read from the fd when
the queue is empty.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
libevdev/libevdev.c
libevdev/libevdev.h
tools/libevdev-events.c

index 590e2d6..b625934 100644 (file)
@@ -556,18 +556,21 @@ int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_e
                        update_state(dev, &e);
        }
 
-       /* FIXME: check for O_NONBLOCK and if not set, skip if we have an
-        * event in the queue from the previous read.
-        */
-
        /* FIXME: if the first event after syncing is a SYN_DROPPED, log this */
 
        /* Always read in some more events. Best case this smoothes over a potential SYN_DROPPED,
-          worst case we don't read fast enough and end up with SYN_DROPPED anyway */
+          worst case we don't read fast enough and end up with SYN_DROPPED anyway.
+
+          Except if the fd is in blocking mode and we still have events from the last read, don't
+          read in any more.
+        */
        do {
-               rc = read_more_events(dev);
-               if (rc < 0 && rc != -EAGAIN)
-                       goto out;
+               if (!(flags & LIBEVDEV_READ_BLOCKING) ||
+                   queue_num_elements(dev) == 0) {
+                       rc = read_more_events(dev);
+                       if (rc < 0 && rc != -EAGAIN)
+                               goto out;
+               }
 
                if (flags & LIBEVDEV_FORCE_SYNC) {
                        dev->need_sync = 1;
index 7e4c247..db8fd88 100644 (file)
@@ -192,6 +192,7 @@ enum EvdevReadFlags {
        LIBEVDEV_FORCE_SYNC             = 4, /**< Pretend the next event is a SYN_DROPPED. There is
                                                  no reason to ever use this except for
                                                  automated tests, so don't. */
+       LIBEVDEV_READ_BLOCKING          = 8, /**< The fd is not in O_NONBLOCK and a read may block */
 };
 
 /**
index e7728e7..ee64cea 100644 (file)
@@ -145,7 +145,7 @@ main(int argc, char **argv)
                goto out;
 
        file = argv[1];
-       fd = open(file, O_RDONLY | O_NONBLOCK);
+       fd = open(file, O_RDONLY);
        if (fd < 0) {
                perror("Failed to open device");
                goto out;
@@ -170,7 +170,7 @@ main(int argc, char **argv)
 
        do {
                struct input_event ev;
-               rc = libevdev_next_event(dev, LIBEVDEV_READ_NORMAL, &ev);
+               rc = libevdev_next_event(dev, LIBEVDEV_READ_NORMAL|LIBEVDEV_READ_BLOCKING, &ev);
                if (rc == 1) {
                        printf("::::::::::::::::::::: dropped ::::::::::::::::::::::\n");
                        while (rc == 1) {