X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=libmainloop%2Fselect.c;h=14070aabe6814a94a3e21838fcd8e34081c90155;hp=28762222b609eb90a0272693577cbb1a95318993;hb=HEAD;hpb=8366314611bf30a0f31d25bf5f5023186fa87692 diff --git a/libmainloop/select.c b/libmainloop/select.c index 2876222..14070aa 100644 --- a/libmainloop/select.c +++ b/libmainloop/select.c @@ -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 +#include +#include + #include #include #include #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); }