@ -63,6 +63,8 @@ static bool do_sigchld = false;
static struct uloop_fd_event cur_fds [ ULOOP_MAX_EVENTS ] ;
static int cur_fd , cur_nfds ;
int uloop_fd_add ( struct uloop_fd * sock , unsigned int flags ) ;
# ifdef USE_KQUEUE
# include "uloop-kqueue.c"
# endif
@ -71,6 +73,59 @@ static int cur_fd, cur_nfds;
# include "uloop-epoll.c"
# endif
static void waker_consume ( struct uloop_fd * fd , unsigned int events )
{
char buf [ 4 ] ;
while ( read ( fd - > fd , buf , 4 ) > 0 )
;
}
static int waker_pipe = - 1 ;
static struct uloop_fd waker_fd = {
. fd = - 1 ,
. cb = waker_consume ,
} ;
static void waker_init_fd ( int fd )
{
fcntl ( fd , F_SETFD , fcntl ( fd , F_GETFD ) | FD_CLOEXEC ) ;
fcntl ( fd , F_SETFL , fcntl ( fd , F_GETFL ) | O_NONBLOCK ) ;
}
static int waker_init ( void )
{
int fds [ 2 ] ;
if ( waker_pipe > = 0 )
return 0 ;
if ( pipe ( fds ) < 0 )
return - 1 ;
waker_init_fd ( fds [ 0 ] ) ;
waker_init_fd ( fds [ 1 ] ) ;
waker_fd . fd = fds [ 0 ] ;
waker_fd . cb = waker_consume ;
uloop_fd_add ( & waker_fd , ULOOP_READ ) ;
return 0 ;
}
int uloop_init ( void )
{
if ( uloop_init_pollfd ( ) < 0 )
return - 1 ;
if ( waker_init ( ) < 0 ) {
uloop_done ( ) ;
return - 1 ;
}
return 0 ;
}
static bool uloop_fd_stack_event ( struct uloop_fd * fd , int events )
{
struct uloop_fd_stack * cur ;
@ -328,14 +383,21 @@ static void uloop_handle_processes(void)
}
static void uloop_signal_wake ( void )
{
write ( waker_pipe , " w " , 1 ) ;
}
static void uloop_handle_sigint ( int signo )
{
uloop_cancelled = true ;
uloop_signal_wake ( ) ;
}
static void uloop_sigchld ( int signo )
{
do_sigchld = true ;
uloop_signal_wake ( ) ;
}
static void uloop_install_handler ( int signum , void ( * handler ) ( int ) , struct sigaction * old , bool add )
@ -477,11 +539,17 @@ void uloop_run(void)
void uloop_done ( void )
{
if ( poll_fd < 0 )
return ;
if ( poll_fd > = 0 ) {
close ( poll_fd ) ;
poll_fd = - 1 ;
}
close ( poll_fd ) ;
poll_fd = - 1 ;
if ( waker_pipe > = 0 ) {
uloop_fd_delete ( & waker_fd ) ;
close ( waker_pipe ) ;
close ( waker_fd . fd ) ;
waker_pipe = - 1 ;
}
uloop_clear_timeouts ( ) ;
uloop_clear_processes ( ) ;