python: attempt to use dc_event_emitter_close()

This commit is contained in:
link2xt
2022-05-03 22:14:54 +00:00
parent eb3242e077
commit 69ea56eb75
2 changed files with 13 additions and 24 deletions

View File

@@ -699,14 +699,7 @@ class Account(object):
self.log("remove dc_context references") self.log("remove dc_context references")
# if _dc_context is unref'ed the event thread should quickly
# receive the termination signal. However, some python code might
# still hold a reference and so we use a secondary signal
# to make sure the even thread terminates if it receives any new
# event, indepedently from waiting for the core to send NULL to
# get_next_event().
self._event_thread.mark_shutdown() self._event_thread.mark_shutdown()
self._dc_context = None
self.log("wait for event thread to finish") self.log("wait for event thread to finish")
try: try:
@@ -714,6 +707,8 @@ class Account(object):
except RuntimeError as e: except RuntimeError as e:
self.log("Waiting for event thread failed: {}".format(e)) self.log("Waiting for event thread failed: {}".format(e))
self._dc_context = None
if self._event_thread.is_alive(): if self._event_thread.is_alive():
self.log("WARN: event thread did not terminate yet, ignoring.") self.log("WARN: event thread did not terminate yet, ignoring.")

View File

@@ -196,7 +196,7 @@ class EventThread(threading.Thread):
self.account = account self.account = account
super(EventThread, self).__init__(name="events") super(EventThread, self).__init__(name="events")
self.daemon = True self.daemon = True
self._marked_for_shutdown = False self._event_emitter = None
self.start() self.start()
@contextmanager @contextmanager
@@ -206,7 +206,7 @@ class EventThread(threading.Thread):
self.account.log(message + " FINISHED") self.account.log(message + " FINISHED")
def mark_shutdown(self) -> None: def mark_shutdown(self) -> None:
self._marked_for_shutdown = True lib.dc_event_emitter_close(self._event_emitter)
def wait(self, timeout=None) -> None: def wait(self, timeout=None) -> None:
if self == threading.current_thread(): if self == threading.current_thread():
@@ -221,18 +221,16 @@ class EventThread(threading.Thread):
self._inner_run() self._inner_run()
def _inner_run(self): def _inner_run(self):
if self._marked_for_shutdown or self.account._dc_context is None: if self.account._dc_context is None:
return return
event_emitter = ffi.gc( self._event_emitter = ffi.gc(
lib.dc_get_event_emitter(self.account._dc_context), lib.dc_get_event_emitter(self.account._dc_context),
lib.dc_event_emitter_unref, lib.dc_event_emitter_unref,
) )
while not self._marked_for_shutdown: while True:
event = lib.dc_get_next_event(event_emitter) event = lib.dc_get_next_event(self._event_emitter)
if event == ffi.NULL: if event == ffi.NULL:
break break
if self._marked_for_shutdown:
break
evt = lib.dc_event_get_id(event) evt = lib.dc_event_get_id(event)
data1 = lib.dc_event_get_data1_int(event) data1 = lib.dc_event_get_data1_int(event)
# the following code relates to the deltachat/_build.py's helper # the following code relates to the deltachat/_build.py's helper
@@ -245,15 +243,11 @@ class EventThread(threading.Thread):
lib.dc_event_unref(event) lib.dc_event_unref(event)
ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2) ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2)
try: self.account._pm.hook.ac_process_ffi_event(account=self, ffi_event=ffi_event)
self.account._pm.hook.ac_process_ffi_event(account=self, ffi_event=ffi_event) for name, kwargs in self._map_ffi_event(ffi_event):
for name, kwargs in self._map_ffi_event(ffi_event): self.account.log("calling hook name={} kwargs={}".format(name, kwargs))
self.account.log("calling hook name={} kwargs={}".format(name, kwargs)) hook = getattr(self.account._pm.hook, name)
hook = getattr(self.account._pm.hook, name) hook(**kwargs)
hook(**kwargs)
except Exception:
if not self._marked_for_shutdown and self.account._dc_context is not None:
raise
def _map_ffi_event(self, ffi_event: FFIEvent): def _map_ffi_event(self, ffi_event: FFIEvent):
name = ffi_event.name name = ffi_event.name