Make MtProtoSender not thread-safe

Rationale: a new connection should be spawned if one desires to
send and receive requests in parallel, which would otherwise cause
one of either threads to lock.
This commit is contained in:
Lonami Exo 2017-09-30 11:49:38 +02:00
parent 003e231239
commit 5da300ca84

View File

@ -1,7 +1,6 @@
import gzip
import logging
import struct
from threading import RLock
from .. import helpers as utils
from ..crypto import AES
@ -20,7 +19,12 @@ logging.getLogger(__name__).addHandler(logging.NullHandler())
class MtProtoSender:
"""MTProto Mobile Protocol sender
(https://core.telegram.org/mtproto/description)
(https://core.telegram.org/mtproto/description).
Note that this class is not thread-safe, and calling send/receive
from two or more threads at the same time is undefined behaviour.
Rationale: a new connection should be spawned to send/receive requests
in parallel, so thread-safety (hence locking) isn't needed.
"""
def __init__(self, session, connection):
@ -37,11 +41,6 @@ class MtProtoSender:
# Requests (as msg_id: Message) sent waiting to be received
self._pending_receive = {}
# Sending and receiving are independent, but two threads cannot
# send or receive at the same time no matter what.
self._send_lock = RLock()
self._recv_lock = RLock()
def connect(self):
"""Connects to the server"""
self.connection.connect()
@ -93,7 +92,6 @@ class MtProtoSender:
Any unhandled object (likely updates) will be passed to
update_state.process(TLObject).
"""
with self._recv_lock:
try:
body = self.connection.recv()
except (BufferError, InvalidChecksumError):
@ -128,7 +126,6 @@ class MtProtoSender:
cipher_text = AES.encrypt_ige(plain_text, key, iv)
result = key_id + msg_key + cipher_text
with self._send_lock:
self.connection.send(result)
def _decode_msg(self, body):