@@ -427,7 +427,7 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist,
427427 return ret ;
428428}
429429
430- #if defined(HAVE_POLL ) && !defined(HAVE_BROKEN_POLL )
430+ #if ( defined(HAVE_POLL ) || defined( HAVE_PPOLL ) ) && !defined(HAVE_BROKEN_POLL )
431431/*
432432 * poll() support
433433 */
@@ -626,7 +626,7 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
626626 PyObject * result_list = NULL ;
627627 int poll_result , i , j ;
628628 PyObject * value = NULL , * num = NULL ;
629- PyTime_t timeout = -1 , ms = -1 , deadline = 0 ;
629+ PyTime_t timeout = -1 , deadline = 0 ;
630630 int async_err = 0 ;
631631
632632 if (timeout_obj != Py_None ) {
@@ -639,15 +639,28 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
639639 }
640640 return NULL ;
641641 }
642+ }
642643
643- ms = _PyTime_AsMilliseconds (timeout , _PyTime_ROUND_TIMEOUT );
644- if (ms < INT_MIN || ms > INT_MAX ) {
645- PyErr_SetString (PyExc_OverflowError , "timeout is too large" );
644+ #ifdef HAVE_PPOLL
645+ struct timespec ts , * ts_p = NULL ;
646+
647+ if (timeout_obj != Py_None ) {
648+ if (_PyTime_AsTimespec (timeout , & ts ) < 0 ) {
646649 return NULL ;
647650 }
648651
649652 if (timeout >= 0 ) {
650- deadline = _PyDeadline_Init (timeout );
653+ ts_p = & ts ;
654+ }
655+ }
656+ #else
657+ PyTime_t ms = -1 ;
658+
659+ if (timeout_obj != Py_None ) {
660+ ms = _PyTime_AsMilliseconds (timeout , _PyTime_ROUND_TIMEOUT );
661+ if (ms < INT_MIN || ms > INT_MAX ) {
662+ PyErr_SetString (PyExc_OverflowError , "timeout is too large" );
663+ return NULL ;
651664 }
652665 }
653666
@@ -661,6 +674,11 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
661674 ms = -1 ;
662675#endif
663676 }
677+ #endif
678+
679+ if (timeout >= 0 ) {
680+ deadline = _PyDeadline_Init (timeout );
681+ }
664682
665683 /* Avoid concurrent poll() invocation, issue 8865 */
666684 if (self -> poll_running ) {
@@ -681,7 +699,11 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
681699 do {
682700 Py_BEGIN_ALLOW_THREADS
683701 errno = 0 ;
702+ #ifdef HAVE_PPOLL
703+ poll_result = ppoll (self -> ufds , self -> ufd_len , ts_p , NULL );
704+ #else
684705 poll_result = poll (self -> ufds , self -> ufd_len , (int )ms );
706+ #endif
685707 Py_END_ALLOW_THREADS
686708
687709 if (errno != EINTR )
@@ -699,8 +721,16 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj)
699721 poll_result = 0 ;
700722 break ;
701723 }
724+ #ifdef HAVE_PPOLL
725+ if (_PyTime_AsTimespec (timeout , & ts ) < 0 ) {
726+ poll_result = -1 ;
727+ break ;
728+ }
729+ assert (ts_p == & ts );
730+ #else
702731 ms = _PyTime_AsMilliseconds (timeout , _PyTime_ROUND_CEILING );
703- /* retry poll() with the recomputed timeout */
732+ #endif
733+ /* retry poll()/ppoll() with the recomputed timeout */
704734 }
705735 } while (1 );
706736
@@ -2466,7 +2496,7 @@ static PyGetSetDef kqueue_queue_getsetlist[] = {
24662496
24672497#include "clinic/selectmodule.c.h"
24682498
2469- #if defined(HAVE_POLL ) && !defined(HAVE_BROKEN_POLL )
2499+ #if ( defined(HAVE_POLL ) || defined( HAVE_PPOLL ) ) && !defined(HAVE_BROKEN_POLL )
24702500
24712501static PyMethodDef poll_methods [] = {
24722502 SELECT_POLL_REGISTER_METHODDEF
@@ -2661,7 +2691,7 @@ _select_exec(PyObject *m)
26612691 ADD_INT (PIPE_BUF );
26622692#endif
26632693
2664- #if defined(HAVE_POLL ) && !defined(HAVE_BROKEN_POLL )
2694+ #if ( defined(HAVE_POLL ) || defined( HAVE_PPOLL ) ) && !defined(HAVE_BROKEN_POLL )
26652695#ifdef __APPLE__
26662696 if (select_have_broken_poll ()) {
26672697 if (PyObject_DelAttrString (m , "poll" ) == -1 ) {
0 commit comments