[PATCH] async I/O bugfix for systems lacking poll(2)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] async I/O bugfix for systems lacking poll(2)

Paolo Bonzini-2
... such as Mac OS X.  When some selectors are closed, select(2) returns
EBADF and does not poll *any selector*; poll(2) instead marks the error
and goes on polling the rest.

With this patch I can use gst-remote to start and stop Seaside or
Swazoo, as much as I want.  Committed to master and stable-3.0.

Paolo

2008-02-26  Paolo Bonzini  <[hidden email]>

        * libgst/events.c: Add _gst_remove_fd_polling_handlers.
        * libgst/events.h: Declare it.
        * libgst/prims.def: Use it.

diff --git a/libgst/events.c b/libgst/events.c
index 8ba0b67..4298e9b 100644
--- a/libgst/events.c
+++ b/libgst/events.c
@@ -192,6 +192,46 @@ _gst_sync_file_polling (int fd,
     return 0;
 }
 
+void
+_gst_remove_fd_polling_handlers (int fd)
+{
+  polling_queue *node, **pprev;
+
+  if (num_used_pollfds == 0)
+    return;
+
+  /* Disable interrupts while playing with global variables */
+  _gst_disable_interrupts ();
+
+  num_used_pollfds = 0;
+  for (node = head, pprev = &head; node; node = *pprev)
+    {
+      struct pollfd *poll = &pollfds[node->poll];
+
+      if (poll->fd == fd)
+ {
+  _gst_async_signal_and_unregister (node->semaphoreOOP);
+
+  /* Pass over the current node */
+  *pprev = node->next;
+  if (p_tail_next == &node->next)
+    p_tail_next = pprev;
+
+  xfree (node);
+ }
+       else
+ {
+  node->poll = num_used_pollfds;
+  pollfds[num_used_pollfds++] = *poll;
+
+  /* Prepare to get the next node */
+  pprev = &(node->next);
+ }
+    }
+
+  _gst_enable_interrupts ();
+}
+
 RETSIGTYPE
 file_polling_handler (int sig)
 {
diff --git a/libgst/events.h b/libgst/events.h
index fea3e77..9759f92 100644
--- a/libgst/events.h
+++ b/libgst/events.h
@@ -78,6 +78,10 @@ extern mst_Boolean _gst_is_timeout_programmed (void)
   ATTRIBUTE_PURE
   ATTRIBUTE_HIDDEN;
 
+/* Fire and remove all I/O handlers for file descriptor FD.  */
+extern void _gst_remove_fd_polling_handlers (int fd)
+  ATTRIBUTE_HIDDEN;
+
 /* Check whether I/O is possible on the FD file descriptor; COND is 0
    to check for pending input, 1 to check for the possibility of doing
    non-blocking output, 2 to check for pending exceptional situations
diff --git a/libgst/prims.def b/libgst/prims.def
index a7a27db..3ecee3f 100644
--- a/libgst/prims.def
+++ b/libgst/prims.def
@@ -5246,8 +5246,8 @@ primitive VMpr_FileDescriptor_fileOp [succeed,fail]
   fd = TO_INT (fileStream->file);
   switch (arg1)
     {
-
     case PRIM_CLOSE_FILE: /* FileDescriptor close */
+      _gst_remove_fd_polling_handlers (fd);
       resultOOP = FROM_INT (close (fd));
       goto succeed;
 
@@ -5550,6 +5550,7 @@ primitive VMpr_FileDescriptor_socketOp [succeed,fail]
 
     case PRIM_CLOSE_FILE: /* FileDescriptor close */
       {
+        _gst_remove_fd_polling_handlers (fd);
         int result = closesocket (fd);
         resultOOP = FROM_INT (result);
         goto succeed;

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk