X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libmainloop%2Fselect.c;h=14070aabe6814a94a3e21838fcd8e34081c90155;hb=HEAD;hp=e66d35ca3d195e11ddf208d38e0e69bf5fc0de40;hpb=d2a43a53786878c1273313249d3b49f6cd559b00;p=ion3.git diff --git a/libmainloop/select.c b/libmainloop/select.c index e66d35c..14070aa 100644 --- a/libmainloop/select.c +++ b/libmainloop/select.c @@ -1,16 +1,21 @@ /* - * ion/libmainloop/mainloop.c + * libmainloop/select.c * * Partly based on a contributed code. * * See the included file LICENSE for details. */ +#include +#include +#include + #include #include #include #include "select.h" +#include "signal.h" /*{{{ File descriptor management */ @@ -94,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); }