]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/select.c
Update svn:keyword properties.
[thirdparty/cups.git] / scheduler / select.c
index 0ac6ce0636c460b7a6575ea771892aa0717f88ee..a44ec2e3f9a44b835e47b0c0751a319e3aae49a5 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * "$Id: select.c 7720 2008-07-11 22:46:21Z mike $"
+ * "$Id$"
  *
- *   Select abstraction functions for the Common UNIX Printing System (CUPS).
+ *   Select abstraction functions for the CUPS scheduler.
  *
- *   Copyright 2007-2009 by Apple Inc.
+ *   Copyright 2007-2012 by Apple Inc.
  *   Copyright 2006-2007 by Easy Software Products.
  *
  *   These coded instructions, statements, and computer programs are the
  */
 
 #include "cupsd.h"
+#undef HAVE_KQUEUE
 
 #ifdef HAVE_EPOLL
 #  include <sys/epoll.h>
-#  include <sys/poll.h>
+#  include <poll.h>
 #elif defined(HAVE_KQUEUE)
 #  include <sys/event.h>
 #  include <sys/time.h>
 #elif defined(HAVE_POLL)
-#  include <sys/poll.h>
+#  include <poll.h>
 #elif defined(__hpux)
 #  include <sys/time.h>
 #else
 /*
  * Design Notes for Poll/Select API in CUPSD
  * -----------------------------------------
- * 
+ *
  * SUPPORTED APIS
- * 
+ *
  *     OS              select  poll    epoll   kqueue  /dev/poll
  *     --------------  ------  ------  ------  ------  ---------
  *     AIX             YES     YES     NO      NO      NO
  *     FreeBSD         YES     YES     NO      YES     NO
  *     HP-UX           YES     YES     NO      NO      NO
- *     IRIX            YES     YES     NO      NO      NO
  *     Linux           YES     YES     YES     NO      NO
  *     MacOS X         YES     YES     NO      YES     NO
  *     NetBSD          YES     YES     NO      YES     NO
  *     Solaris         YES     YES     NO      NO      YES
  *     Tru64           YES     YES     NO      NO      NO
  *     Windows         YES     NO      NO      NO      NO
- * 
- * 
+ *
+ *
  * HIGH-LEVEL API
- * 
+ *
  *     typedef void (*cupsd_selfunc_t)(void *data);
- * 
+ *
  *     void cupsdStartSelect(void);
  *     void cupsdStopSelect(void);
  *     void cupsdAddSelect(int fd, cupsd_selfunc_t read_cb,
  *                         cupsd_selfunc_t write_cb, void *data);
  *     void cupsdRemoveSelect(int fd);
  *     int cupsdDoSelect(int timeout);
- * 
- * 
+ *
+ *
  * IMPLEMENTATION STRATEGY
- * 
+ *
  *     0. Common Stuff
  *         a. CUPS array of file descriptor to callback functions
  *            and data + temporary array of removed fd's.
  *            working sets.
  *         d. cupsdStopSelect() frees all of the memory used by the
  *            CUPS array and fd_set's.
- * 
+ *
  *     2. poll() - O(n log n)
  *         a. Regular array of pollfd, sorted the same as the CUPS
  *            array.
  *         e. cupsdRemoveSelect() flags the pollfd array as invalid.
  *         f. cupsdStopSelect() frees all of the memory used by the
  *            CUPS array and pollfd array.
- * 
+ *
  *     3. epoll() - O(n)
  *         a. cupsdStartSelect() creates epoll file descriptor using
  *            epoll_create() with the maximum fd count, and
  *            the callback record.
  *         d. cupsdStopSelect() closes the epoll file descriptor and
  *            frees all of the memory used by the event buffer.
- * 
+ *
  *     4. kqueue() - O(n)
  *         b. cupsdStartSelect() creates kqueue file descriptor
- *            using kqyeue() function and allocates a global event
+ *            using kqueue() function and allocates a global event
  *            buffer.
  *         c. cupsdAdd/RemoveSelect() uses EV_SET and kevent() to
  *            register the changes. The event user data field is a
  *         d. cupsdDoSelect() uses kevent() to poll for events and
  *            loops through the events, using the user data field to
  *            find the callback record.
- *         e. cupsdStopSelect() closes the kqyeye() file descriptor
+ *         e. cupsdStopSelect() closes the kqueue() file descriptor
  *            and frees all of the memory used by the event buffer.
- * 
+ *
  *     5. /dev/poll - O(n log n) - NOT YET IMPLEMENTED
  *         a. cupsdStartSelect() opens /dev/poll and allocates an
  *            array of pollfd structs; on failure to open /dev/poll,
@@ -268,7 +268,7 @@ cupsdAddSelect(int             fd,  /* I - File descriptor */
   * Range check input...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
                   "cupsdAddSelect(fd=%d, read_cb=%p, write_cb=%p, data=%p)",
                  fd, read_cb, write_cb, data);
 
@@ -454,7 +454,8 @@ cupsdDoSelect(long timeout)         /* I - Timeout in seconds */
     if (fdptr->read_cb && event->filter == EVFILT_READ)
       (*(fdptr->read_cb))(fdptr->data);
 
-    if (fdptr->write_cb && event->filter == EVFILT_WRITE)
+    if (fdptr->use > 1 && fdptr->write_cb && event->filter == EVFILT_WRITE &&
+        !cupsArrayFind(cupsd_inactive_fds, fdptr))
       (*(fdptr->write_cb))(fdptr->data);
 
     release_fd(fdptr);
@@ -499,7 +500,9 @@ cupsdDoSelect(long timeout)         /* I - Timeout in seconds */
        if (fdptr->read_cb && (event->events & (EPOLLIN | EPOLLERR | EPOLLHUP)))
          (*(fdptr->read_cb))(fdptr->data);
 
-       if (fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
+       if (fdptr->use > 1 && fdptr->write_cb &&
+            (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) &&
+            !cupsArrayFind(cupsd_inactive_fds, fdptr))
          (*(fdptr->write_cb))(fdptr->data);
 
        release_fd(fdptr);
@@ -590,7 +593,8 @@ cupsdDoSelect(long timeout)         /* I - Timeout in seconds */
       if (fdptr->read_cb && (pfd->revents & (POLLIN | POLLERR | POLLHUP)))
         (*(fdptr->read_cb))(fdptr->data);
 
-      if (fdptr->write_cb && (pfd->revents & (POLLOUT | POLLERR | POLLHUP)))
+      if (fdptr->use > 1 && fdptr->write_cb &&
+          (pfd->revents & (POLLOUT | POLLERR | POLLHUP)))
         (*(fdptr->write_cb))(fdptr->data);
 
       release_fd(fdptr);
@@ -645,7 +649,8 @@ cupsdDoSelect(long timeout)         /* I - Timeout in seconds */
       if (fdptr->read_cb && FD_ISSET(fdptr->fd, &cupsd_current_input))
         (*(fdptr->read_cb))(fdptr->data);
 
-      if (fdptr->write_cb && FD_ISSET(fdptr->fd, &cupsd_current_output))
+      if (fdptr->use > 1 && fdptr->write_cb &&
+          FD_ISSET(fdptr->fd, &cupsd_current_output))
         (*(fdptr->write_cb))(fdptr->data);
 
       release_fd(fdptr);
@@ -718,7 +723,7 @@ cupsdRemoveSelect(int fd)           /* I - File descriptor */
   * Range check input...
   */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRemoveSelect(fd=%d)", fd);
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdRemoveSelect(fd=%d)", fd);
 
   if (fd < 0)
     return;
@@ -750,7 +755,7 @@ cupsdRemoveSelect(int fd)           /* I - File descriptor */
     {
       cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s",
                      strerror(errno));
-      return;
+      goto cleanup;
     }
   }
 
@@ -762,11 +767,10 @@ cupsdRemoveSelect(int fd)         /* I - File descriptor */
     {
       cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s",
                      strerror(errno));
-      return;
+      goto cleanup;
     }
   }
 
-
 #elif defined(HAVE_POLL)
  /*
   * Update the pollfds array...
@@ -781,6 +785,10 @@ cupsdRemoveSelect(int fd)          /* I - File descriptor */
   FD_CLR(fd, &cupsd_current_output);
 #endif /* HAVE_EPOLL */
 
+#ifdef HAVE_KQUEUE
+  cleanup:
+#endif /* HAVE_KQUEUE */
+
  /*
   * Remove the file descriptor from the active array and add to the
   * inactive array (or release, if we don't need the inactive array...)
@@ -805,7 +813,7 @@ cupsdRemoveSelect(int fd)           /* I - File descriptor */
 void
 cupsdStartSelect(void)
 {
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSelect()");
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdStartSelect()");
 
   cupsd_fds = cupsArrayNew((cups_array_func_t)compare_fds, NULL);
 
@@ -843,7 +851,7 @@ cupsdStopSelect(void)
   _cupsd_fd_t  *fdptr;                 /* Current file descriptor */
 
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopSelect()");
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdStopSelect()");
 
   for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds);
        fdptr;
@@ -939,5 +947,5 @@ find_fd(int fd)                             /* I - File descriptor */
 
 
 /*
- * End of "$Id: select.c 7720 2008-07-11 22:46:21Z mike $".
+ * End of "$Id$".
  */