diff options
author | Philipp Hörist <philipp@hoerist.com> | 2023-03-18 20:03:28 +0300 |
---|---|---|
committer | Philipp Hörist <philipp@hoerist.com> | 2023-03-18 20:03:28 +0300 |
commit | 45e30be68e80fa21d870d56a49cb1d75ef698f3c (patch) | |
tree | e39613d783522ee30406db0d8214afb65bea738c | |
parent | 63e8fc239732acc3425379843b6d1a597121d416 (diff) |
fix: HTTP: Make sure streams are closed only once
Stream.close() can have side effects which lead to the method
beeing called twice in the same Mainloop iteration.
-rw-r--r-- | nbxmpp/http.py | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/nbxmpp/http.py b/nbxmpp/http.py index ba19d84..d38b05e 100644 --- a/nbxmpp/http.py +++ b/nbxmpp/http.py @@ -483,13 +483,24 @@ class HTTPRequest(GObject.GObject): self._cleanup() def _close_all_streams(self) -> None: - if self._input_stream is not None: - if not self._input_stream.is_closed(): - self._input_stream.close(None) + # stream.close() will invoke signals on the Message object + # which in turn can lead to this method called again in the + # same Mainloop iteration. This means is_closed() will not + # return True and we get an GLib.IOError.PENDING error. - if self._output_stream is not None: - if not self._output_stream.is_closed(): - self._output_stream.close(None) + input_stream = self._input_stream + output_stream = self._output_stream + + self._input_stream = None + self._output_stream = None + + if input_stream is not None: + if not input_stream.is_closed(): + input_stream.close(None) + + if output_stream is not None: + if not output_stream.is_closed(): + output_stream.close(None) def _cleanup(self) -> None: self._log.info('Run cleanup') @@ -501,9 +512,6 @@ class HTTPRequest(GObject.GObject): del self._session del self._user_data - self._input_stream = None - self._output_stream = None - if self._timeout_id is not None: GLib.source_remove(self._timeout_id) self._timeout_id = None |