@ -1326,6 +1326,10 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
* in the set at all times and just disarm it when it ' s not needed . For kqueue ,
* in the set at all times and just disarm it when it ' s not needed . For kqueue ,
* the timer is removed completely when disabled to prevent stale timeouts from
* the timer is removed completely when disabled to prevent stale timeouts from
* remaining in the queue .
* remaining in the queue .
*
* To meet Curl requirements for the CURLMOPT_TIMERFUNCTION , implementations of
* set_timer must handle repeated calls by fully discarding any previous running
* or expired timer .
*/
*/
static bool
static bool
set_timer ( struct async_ctx * actx , long timeout )
set_timer ( struct async_ctx * actx , long timeout )
@ -1373,26 +1377,44 @@ set_timer(struct async_ctx *actx, long timeout)
timeout = 1 ;
timeout = 1 ;
# endif
# endif
/* Enable/disable the timer itself. */
/*
EV_SET ( & ev , 1 , EVFILT_TIMER , timeout < 0 ? EV_DELETE : ( EV_ADD | EV_ONESHOT ) ,
* Always disable the timer , and remove it from the multiplexer , to clear
0 , timeout , 0 ) ;
* out any already - queued events . ( On some BSDs , adding an EVFILT_TIMER to
* a kqueue that already has one will clear stale events , but not on
* macOS . )
*
* If there was no previous timer set , the kevent calls will result in
* ENOENT , which is fine .
*/
EV_SET ( & ev , 1 , EVFILT_TIMER , EV_DELETE , 0 , 0 , 0 ) ;
if ( kevent ( actx - > timerfd , & ev , 1 , NULL , 0 , NULL ) < 0 & & errno ! = ENOENT )
if ( kevent ( actx - > timerfd , & ev , 1 , NULL , 0 , NULL ) < 0 & & errno ! = ENOENT )
{
{
actx_error ( actx , " setting kqueue timer to %ld: %m " , timeout ) ;
actx_error ( actx , " deleting kqueue timer : %m" , timeout ) ;
return false ;
return false ;
}
}
/*
EV_SET ( & ev , actx - > timerfd , EVFILT_READ , EV_DELETE , 0 , 0 , 0 ) ;
* Add / remove the timer to / from the mux . ( In contrast with epoll , if we
* allowed the timer to remain registered here after being disabled , the
* mux queue would retain any previous stale timeout notifications and
* remain readable . )
*/
EV_SET ( & ev , actx - > timerfd , EVFILT_READ , timeout < 0 ? EV_DELETE : EV_ADD ,
0 , 0 , 0 ) ;
if ( kevent ( actx - > mux , & ev , 1 , NULL , 0 , NULL ) < 0 & & errno ! = ENOENT )
if ( kevent ( actx - > mux , & ev , 1 , NULL , 0 , NULL ) < 0 & & errno ! = ENOENT )
{
{
actx_error ( actx , " could not update timer on kqueue: %m " ) ;
actx_error ( actx , " removing kqueue timer from multiplexer: %m " ) ;
return false ;
}
/* If we're not adding a timer, we're done. */
if ( timeout < 0 )
return true ;
EV_SET ( & ev , 1 , EVFILT_TIMER , ( EV_ADD | EV_ONESHOT ) , 0 , timeout , 0 ) ;
if ( kevent ( actx - > timerfd , & ev , 1 , NULL , 0 , NULL ) < 0 )
{
actx_error ( actx , " setting kqueue timer to %ld: %m " , timeout ) ;
return false ;
}
EV_SET ( & ev , actx - > timerfd , EVFILT_READ , EV_ADD , 0 , 0 , 0 ) ;
if ( kevent ( actx - > mux , & ev , 1 , NULL , 0 , NULL ) < 0 )
{
actx_error ( actx , " adding kqueue timer to multiplexer: %m " ) ;
return false ;
return false ;
}
}