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 gzip
import logging import logging
import struct import struct
from threading import RLock
from .. import helpers as utils from .. import helpers as utils
from ..crypto import AES from ..crypto import AES
@ -20,7 +19,12 @@ logging.getLogger(__name__).addHandler(logging.NullHandler())
class MtProtoSender: class MtProtoSender:
"""MTProto Mobile Protocol sender """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): def __init__(self, session, connection):
@ -37,11 +41,6 @@ class MtProtoSender:
# Requests (as msg_id: Message) sent waiting to be received # Requests (as msg_id: Message) sent waiting to be received
self._pending_receive = {} 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): def connect(self):
"""Connects to the server""" """Connects to the server"""
self.connection.connect() self.connection.connect()
@ -93,7 +92,6 @@ class MtProtoSender:
Any unhandled object (likely updates) will be passed to Any unhandled object (likely updates) will be passed to
update_state.process(TLObject). update_state.process(TLObject).
""" """
with self._recv_lock:
try: try:
body = self.connection.recv() body = self.connection.recv()
except (BufferError, InvalidChecksumError): except (BufferError, InvalidChecksumError):
@ -128,7 +126,6 @@ class MtProtoSender:
cipher_text = AES.encrypt_ige(plain_text, key, iv) cipher_text = AES.encrypt_ige(plain_text, key, iv)
result = key_id + msg_key + cipher_text result = key_id + msg_key + cipher_text
with self._send_lock:
self.connection.send(result) self.connection.send(result)
def _decode_msg(self, body): def _decode_msg(self, body):