]> git.decadent.org.uk Git - ion3.git/blobdiff - libmainloop/select.c
Update cfg_kludge_flash for Flash 10
[ion3.git] / libmainloop / select.c
index 28762222b609eb90a0272693577cbb1a95318993..14070aabe6814a94a3e21838fcd8e34081c90155 100644 (file)
@@ -1,19 +1,21 @@
 /*
- * ion/libmainloop/mainloop.c
+ * libmainloop/select.c
  * 
  * Partly based on a contributed code.
  *
- * Ion is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
  */
 
+#include <signal.h>
+#include <sys/select.h>
+#include <errno.h>
+
 #include <libtu/types.h>
 #include <libtu/misc.h>
 #include <libtu/dlist.h>
 
 #include "select.h"
+#include "signal.h"
 
 
 /*{{{ File descriptor management */
@@ -97,12 +99,49 @@ void mainloop_select()
 {
     fd_set rfds;
     int nfds=0;
-            
-    FD_ZERO(&rfds);
+    int ret=0;
     
-    set_input_fds(&rfds, &nfds);
     
-    if(select(nfds+1, &rfds, NULL, NULL, NULL)>0)
+#ifdef _POSIX_SELECT
+    {
+        sigset_t oldmask;
+
+        FD_ZERO(&rfds);
+        set_input_fds(&rfds, &nfds);
+        
+        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};
+        
+        /* 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().
+         */
+        do{
+            FD_ZERO(&rfds);
+            set_input_fds(&rfds, &nfds);
+            
+            bool to=libmainloop_get_timeout(&tv);
+            
+            if(mainloop_unhandled_signals()){
+                ret=0;
+                break;
+            }
+            
+            ret=select(nfds+1, &rfds, NULL, NULL, to ? &tv : NULL);
+        }while(ret<0 && errno==EINTR && !mainloop_unhandled_signals());
+    }
+#endif
+    if(ret>0)
         check_input_fds(&rfds);
 }