From 8be7e76b741db51f7160d0e8868b089aa029e77f Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Sun, 14 Jan 2018 21:20:22 +0100 Subject: [PATCH] Use the idling state instead checking if read thread is present This caused some multithreading bugs, for instance, when there was no read thread and the main thread was idling, and there were some update workers. Several threads would try to read from the socket at the same time (since there's no lock for reading), causing reads to be corrupted and receiving "invalid packet lengths" from the network. Closes #538. --- telethon/telegram_bare_client.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/telethon/telegram_bare_client.py b/telethon/telegram_bare_client.py index 8adf2567..2c1b6188 100644 --- a/telethon/telegram_bare_client.py +++ b/telethon/telegram_bare_client.py @@ -163,6 +163,7 @@ class TelegramBareClient: # if the user has left enabled such option. self._spawn_read_thread = spawn_read_thread self._recv_thread = None + self._idling = threading.Event() # Default PingRequest delay self._last_ping = datetime.now() @@ -438,8 +439,9 @@ class TelegramBareClient: # Determine the sender to be used (main or a new connection) __log__.debug('Invoking %s', which) + call_receive = \ + not self._idling.is_set() or self._reconnect_lock.locked() - call_receive = self._recv_thread is None or self._reconnect_lock.locked() for retry in range(retries): result = self._invoke(call_receive, *requests) if result is not None: @@ -829,6 +831,7 @@ class TelegramBareClient: if self._spawn_read_thread and not self._on_read_thread(): raise RuntimeError('Can only idle if spawn_read_thread=False') + self._idling.set() for sig in stop_signals: signal(sig, self._signal_handler) @@ -857,7 +860,11 @@ class TelegramBareClient: with self._reconnect_lock: while self._user_connected and not self._reconnect(): sleep(0.1) # Retry forever, this is instant messaging + except: + self._idling.clear() + raise + self._idling.clear() __log__.info('Connection closed by the user, not reading anymore') # By using this approach, another thread will be