20
20
*/
21
21
#include <errno.h>
22
22
#include <poll.h>
23
+ #include <sys/timerfd.h>
24
+ #include <time.h>
23
25
#include "sd_bus_internals.h"
24
26
25
27
static void SdBus_dealloc (SdBusObject * self ) {
26
28
if (NULL != self -> loop && NULL != self -> bus_fd ) {
27
29
Py_XDECREF (PyObject_CallMethodObjArgs (self -> loop , remove_reader_str , self -> bus_fd , NULL ));
28
30
Py_XDECREF (PyObject_CallMethodObjArgs (self -> loop , remove_writer_str , self -> bus_fd , NULL ));
29
31
}
32
+ if (NULL != self -> timer_fd ) {
33
+ Py_XDECREF (PyObject_CallMethodObjArgs (self -> loop , remove_reader_str , self -> bus_fd , NULL ));
34
+ Py_DECREF (self -> timer_fd );
35
+ close (self -> timer_fd_int );
36
+ }
30
37
sd_bus_unref (self -> sd_bus_ref );
31
38
Py_XDECREF (self -> bus_fd );
32
39
Py_XDECREF (self -> loop );
@@ -623,6 +630,10 @@ static PyObject* SdBus_close(SdBusObject* self, PyObject* Py_UNUSED(args)) {
623
630
Py_XDECREF (CALL_PYTHON_AND_CHECK (PyObject_CallMethodObjArgs (self -> loop , remove_reader_str , self -> bus_fd , NULL )));
624
631
Py_XDECREF (CALL_PYTHON_AND_CHECK (PyObject_CallMethodObjArgs (self -> loop , remove_writer_str , self -> bus_fd , NULL )));
625
632
}
633
+ if (NULL != self -> timer_fd ) {
634
+ Py_XDECREF (PyObject_CallMethodObjArgs (self -> loop , remove_reader_str , self -> bus_fd , NULL ));
635
+ // TODO: Close timerfd
636
+ }
626
637
Py_RETURN_NONE ;
627
638
}
628
639
@@ -639,7 +650,45 @@ static inline int sd_bus_get_events_zero_on_closed(SdBusObject* self) {
639
650
return events ;
640
651
};
641
652
653
+ static inline int sd_bus_get_timeout_uint_max_on_closed (SdBusObject * self , uint64_t * timeout_usec ) {
654
+ int r = sd_bus_get_timeout (self -> sd_bus_ref , timeout_usec );
655
+ if (- ENOTCONN == r ) {
656
+ * timeout_usec = UINT64_MAX ;
657
+ return 0 ;
658
+ }
659
+ return r ;
660
+ }
661
+
642
662
static PyObject * SdBus_asyncio_update_fd_watchers (SdBusObject * self ) {
663
+ PyObject * running_loop = CALL_PYTHON_AND_CHECK (_get_or_bind_loop (self ));
664
+ PyObject * drive_method CLEANUP_PY_OBJECT = CALL_PYTHON_AND_CHECK (PyObject_GetAttrString ((PyObject * )self , "process" ));
665
+
666
+ if (NULL == self -> timer_fd ) {
667
+ self -> timer_fd_int = CALL_SD_BUS_AND_CHECK (timerfd_create (CLOCK_MONOTONIC , TFD_NONBLOCK | TFD_CLOEXEC ));
668
+ if (self -> timer_fd_int < 0 ) {
669
+ PyErr_SetFromErrno (PyExc_OSError );
670
+ }
671
+ PyObject * timer_fd CLEANUP_PY_OBJECT = PyLong_FromLong ((int )self -> timer_fd_int );
672
+ Py_XDECREF (CALL_PYTHON_AND_CHECK (PyObject_CallMethodObjArgs (running_loop , add_reader_str , timer_fd , drive_method , NULL )));
673
+ Py_INCREF (timer_fd );
674
+ self -> timer_fd = timer_fd ;
675
+ }
676
+
677
+ uint64_t timeout_usec = UINT64_MAX ;
678
+ CALL_SD_BUS_AND_CHECK (sd_bus_get_timeout_uint_max_on_closed (self , & timeout_usec ));
679
+
680
+ struct itimerspec bus_timer = {0 };
681
+ if (timeout_usec == UINT64_MAX ) {
682
+ // Setting bus_timer to zero disarms timer.
683
+ } else if (timeout_usec != 0 ) {
684
+ bus_timer .it_value .tv_sec = timeout_usec / 1000000 ;
685
+ bus_timer .it_value .tv_nsec = (timeout_usec % 1000000 ) * 1000 ;
686
+ } else if (timeout_usec == 0 ) {
687
+ Py_XDECREF (CALL_PYTHON_AND_CHECK (PyObject_CallMethodObjArgs (running_loop , call_soon_str , drive_method , NULL )));
688
+ }
689
+
690
+ CALL_SD_BUS_AND_CHECK (timerfd_settime (self -> timer_fd_int , TFD_TIMER_ABSTIME , & bus_timer , NULL ));
691
+
643
692
int events_to_watch = CALL_SD_BUS_AND_CHECK (sd_bus_get_events_zero_on_closed (self ));
644
693
if (events_to_watch == self -> asyncio_watchers_last_state ) {
645
694
// Do not update the watchers because state is the same
@@ -648,9 +697,6 @@ static PyObject* SdBus_asyncio_update_fd_watchers(SdBusObject* self) {
648
697
self -> asyncio_watchers_last_state = events_to_watch ;
649
698
}
650
699
651
- PyObject * running_loop = CALL_PYTHON_AND_CHECK (_get_or_bind_loop (self ));
652
- PyObject * drive_method CLEANUP_PY_OBJECT = CALL_PYTHON_AND_CHECK (PyObject_GetAttrString ((PyObject * )self , "process" ));
653
-
654
700
if (NULL == self -> bus_fd ) {
655
701
self -> bus_fd = CALL_PYTHON_AND_CHECK (SdBus_get_fd (self , NULL ));
656
702
}
0 commit comments