@@ -876,82 +876,102 @@ static PyObject *
876876devpoll_poll (devpollObject * self , PyObject * args )
877877{
878878 struct dvpoll dvp ;
879- PyObject * result_list = NULL , * tout = NULL ;
879+ PyObject * result_list = NULL , * timeout_obj = NULL ;
880880 int poll_result , i ;
881- long timeout ;
882881 PyObject * value , * num1 , * num2 ;
882+ _PyTime_t timeout , ms , deadline = 0 ;
883883
884884 if (self -> fd_devpoll < 0 )
885885 return devpoll_err_closed ();
886886
887- if (!PyArg_UnpackTuple (args , "poll" , 0 , 1 , & tout )) {
887+ if (!PyArg_ParseTuple (args , "|O: poll" , & timeout_obj )) {
888888 return NULL ;
889889 }
890890
891891 /* Check values for timeout */
892- if (tout == NULL || tout == Py_None )
892+ if (timeout_obj == NULL || timeout_obj == Py_None ) {
893893 timeout = -1 ;
894- else if (!PyNumber_Check (tout )) {
895- PyErr_SetString (PyExc_TypeError ,
896- "timeout must be an integer or None" );
897- return NULL ;
894+ ms = -1 ;
898895 }
899896 else {
900- tout = PyNumber_Long ( tout );
901- if (! tout )
902- return NULL ;
903- timeout = PyLong_AsLong ( tout );
904- Py_DECREF ( tout );
905- if ( timeout == -1 && PyErr_Occurred ())
897+ if ( _PyTime_FromMillisecondsObject ( & timeout , timeout_obj ,
898+ _PyTime_ROUND_CEILING ) < 0 ) {
899+ if ( PyErr_ExceptionMatches ( PyExc_TypeError )) {
900+ PyErr_SetString ( PyExc_TypeError ,
901+ "timeout must be an integer or None" );
902+ }
906903 return NULL ;
907- }
904+ }
908905
909- if ((timeout < -1 ) || (timeout > INT_MAX )) {
910- PyErr_SetString (PyExc_OverflowError ,
911- "timeout is out of range" );
912- return NULL ;
906+ ms = _PyTime_AsMilliseconds (timeout , _PyTime_ROUND_CEILING );
907+ if (ms < -1 || ms > INT_MAX ) {
908+ PyErr_SetString (PyExc_OverflowError , "timeout is too large" );
909+ return NULL ;
910+ }
913911 }
914912
915913 if (devpoll_flush (self ))
916914 return NULL ;
917915
918916 dvp .dp_fds = self -> fds ;
919917 dvp .dp_nfds = self -> max_n_fds ;
920- dvp .dp_timeout = timeout ;
918+ dvp .dp_timeout = (int )ms ;
919+
920+ if (timeout >= 0 )
921+ deadline = _PyTime_GetMonotonicClock () + timeout ;
922+
923+ do {
924+ /* call devpoll() */
925+ Py_BEGIN_ALLOW_THREADS
926+ errno = 0 ;
927+ poll_result = ioctl (self -> fd_devpoll , DP_POLL , & dvp );
928+ Py_END_ALLOW_THREADS
929+
930+ if (errno != EINTR )
931+ break ;
921932
922- /* call devpoll() */
923- Py_BEGIN_ALLOW_THREADS
924- poll_result = ioctl (self -> fd_devpoll , DP_POLL , & dvp );
925- Py_END_ALLOW_THREADS
933+ /* devpoll() was interrupted by a signal */
934+ if (PyErr_CheckSignals ())
935+ return NULL ;
936+
937+ if (timeout >= 0 ) {
938+ timeout = deadline - _PyTime_GetMonotonicClock ();
939+ if (timeout < 0 ) {
940+ poll_result = 0 ;
941+ break ;
942+ }
943+ ms = _PyTime_AsMilliseconds (timeout , _PyTime_ROUND_CEILING );
944+ dvp .dp_timeout = (int )ms ;
945+ /* retry devpoll() with the recomputed timeout */
946+ }
947+ } while (1 );
926948
927949 if (poll_result < 0 ) {
928950 PyErr_SetFromErrno (PyExc_IOError );
929951 return NULL ;
930952 }
931953
932954 /* build the result list */
933-
934955 result_list = PyList_New (poll_result );
935956 if (!result_list )
936957 return NULL ;
937- else {
938- for (i = 0 ; i < poll_result ; i ++ ) {
939- num1 = PyLong_FromLong (self -> fds [i ].fd );
940- num2 = PyLong_FromLong (self -> fds [i ].revents );
941- if ((num1 == NULL ) || (num2 == NULL )) {
942- Py_XDECREF (num1 );
943- Py_XDECREF (num2 );
944- goto error ;
945- }
946- value = PyTuple_Pack (2 , num1 , num2 );
947- Py_DECREF (num1 );
948- Py_DECREF (num2 );
949- if (value == NULL )
950- goto error ;
951- if ((PyList_SetItem (result_list , i , value )) == -1 ) {
952- Py_DECREF (value );
953- goto error ;
954- }
958+
959+ for (i = 0 ; i < poll_result ; i ++ ) {
960+ num1 = PyLong_FromLong (self -> fds [i ].fd );
961+ num2 = PyLong_FromLong (self -> fds [i ].revents );
962+ if ((num1 == NULL ) || (num2 == NULL )) {
963+ Py_XDECREF (num1 );
964+ Py_XDECREF (num2 );
965+ goto error ;
966+ }
967+ value = PyTuple_Pack (2 , num1 , num2 );
968+ Py_DECREF (num1 );
969+ Py_DECREF (num2 );
970+ if (value == NULL )
971+ goto error ;
972+ if ((PyList_SetItem (result_list , i , value )) == -1 ) {
973+ Py_DECREF (value );
974+ goto error ;
955975 }
956976 }
957977
0 commit comments