]> git.decadent.org.uk Git - ion3.git/blobdiff - libmainloop/select.c
[svn-upgrade] Integrating new upstream version, ion3 (20080707)
[ion3.git] / libmainloop / select.c
index e66d35ca3d195e11ddf208d38e0e69bf5fc0de40..f8410a5b846c46b318deb3d1a039576c0b0b6618 100644 (file)
@@ -1,16 +1,20 @@
 /*
- * ion/libmainloop/mainloop.c
+ * libmainloop/select.c
  * 
  * Partly based on a contributed code.
  *
  * See the included file LICENSE for details.
  */
 
+#include <signal.h>
+#include <sys/select.h>
+
 #include <libtu/types.h>
 #include <libtu/misc.h>
 #include <libtu/dlist.h>
 
 #include "select.h"
+#include "signal.h"
 
 
 /*{{{ File descriptor management */
@@ -94,12 +98,41 @@ void mainloop_select()
 {
     fd_set rfds;
     int nfds=0;
-            
+    int ret=0;
+    
     FD_ZERO(&rfds);
     
     set_input_fds(&rfds, &nfds);
     
-    if(select(nfds+1, &rfds, NULL, NULL, NULL)>0)
+#ifdef _POSIX_SELECT
+    {
+        sigset_t oldmask;
+        
+        mainloop_block_signals(&oldmask);
+        
+        if(!mainloop_unhandled_signals())
+            ret=pselect(nfds+1, &rfds, NULL, NULL, NULL, &oldmask);
+        
+        sigprocmask(SIG_SETMASK, &oldmask, NULL);
+    }
+#else
+    #warning "pselect() unavailable -- using dirty hacks"
+    {
+        struct timeval tv_={0, 0}, *tv=&tv_;
+        
+        /* If there are timers, make sure we return from select with 
+         * some delay, if the timer signal happens right before
+         * entering select(). Race conditions with other signals
+         * we'll just have to ignore without pselect().
+         */
+        if(!libmainloop_get_timeout(tv))
+            tv=NULL;
+            
+        if(!mainloop_unhandled_signals())
+            ret=select(nfds+1, &rfds, NULL, NULL, tv);
+    }
+#endif
+    if(ret>0)
         check_input_fds(&rfds);
 }