Skip to content

Commit

Permalink
Add tools so can close a dbus service after use.
Browse files Browse the repository at this point in the history
Service will keep the dbus stream open for the life of the application,
this can ause issues on long running daemons. This adds a stop method and
a with processor so that the service can be stopped after use:

service = Service(...)
service.stop()

or

with Service(...) as service:
    -- use the service
  • Loading branch information
charleseidsness committed Jun 24, 2021
1 parent a586d26 commit a5d4840
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
2 changes: 1 addition & 1 deletion adbus/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# == Copyright: 2017-2021, CCX Technologies

__version__ = "1.1.6"
__version__ = "1.2.0"
27 changes: 21 additions & 6 deletions adbus/sdbus/service.pxi
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Copyright: 2017, CCX Technologies
# Copyright: 2017-2021, CCX Technologies
#cython: language_level=3

cdef class Service:
cdef sdbus_h.sd_bus *bus
cdef bytes name
cdef bytes unique_name
cdef bool connected
cdef bool process_loop
cdef stdint.uint64_t flags
cdef object loop
cdef object startup_task

def __cinit__(self, name=None, loop=None, bus='system',
replace_existing=False, allow_replacement=False, queue=False):
Expand Down Expand Up @@ -56,11 +58,27 @@ cdef class Service:
if not loop:
loop = get_event_loop()

loop.create_task(self.startup_process())
self.process_loop = True
self.startup_task = loop.create_task(self.startup_process())
loop.add_reader(bus_fd, self.process)

self.loop = loop

def stop(self):
self.startup_task.cancel()
bus_fd = sdbus_h.sd_bus_get_fd(self.bus)
if bus_fd > 0:
self.loop.remove_reader(bus_fd)
self.process_loop = False

self.bus = sdbus_h.sd_bus_flush_close_unref(self.bus)

def __enter__(self):
return self

def __exit__(self, exception_type, exception_value, exception_traceback):
self.stop()

def is_running(self):
"""Service is running."""
return self.loop.is_running()
Expand All @@ -69,9 +87,6 @@ cdef class Service:
"""Get the service's asyncio loop."""
return self.loop

def __dealloc__(self):
self.bus = sdbus_h.sd_bus_unref(self.bus)

async def startup_process(self):
self.process()

Expand All @@ -88,7 +103,7 @@ cdef class Service:

self.connected = True
try:
while True:
while self.process_loop:
r = sdbus_h.sd_bus_process(self.bus, NULL)

if r < 0:
Expand Down
2 changes: 1 addition & 1 deletion adbus/sdbus_h.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ cdef extern from "systemd/sd-bus.h":
int sd_bus_open_system(sd_bus **ret)
int sd_bus_request_name(sd_bus *bus, const char *name, stdint.uint64_t flags)
int sd_bus_get_unique_name(sd_bus *bus, const char **unique)
sd_bus *sd_bus_unref(sd_bus *bus)
sd_bus *sd_bus_flush_close_unref(sd_bus *bus)

int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot,
const char *path, const char *interface,
Expand Down
9 changes: 9 additions & 0 deletions adbus/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,12 @@ def is_running(self):

def get_loop(self):
return self.sdbus.get_loop()

def stop(self):
self.sdbus.stop()

def __enter__(self):
return self

def __exit__(self, exception_type, exception_value, exception_traceback):
self.stop()

0 comments on commit a5d4840

Please sign in to comment.