From 0ea1c4307fdfd9a0881c589b475f0bd2ef15c9d9 Mon Sep 17 00:00:00 2001 From: Cody Piersall Date: Wed, 29 May 2019 19:46:54 -0500 Subject: [PATCH] Fix a race condition in socket constructor. There was a race where the socket connect callbacks could get called before the socket was added to the global cache. Then, in the callback, the socket would try to be retrieved from the cache, but it wouldn't be there, resulting in an error. This was a pretty bad race, and it affected real code. This was brought up on https://github.com/codypiersall/pynng/issues/40 by GitHub user chaoflow. Many thanks to him for identifying the fix! --- pynng/nng.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pynng/nng.py b/pynng/nng.py index 705ed28..d7710b7 100644 --- a/pynng/nng.py +++ b/pynng/nng.py @@ -300,13 +300,16 @@ def __init__(self, *, check_err(lib.nng_pipe_notify( self.socket, event, lib._nng_pipe_cb, as_void)) + # The socket *must* be added to the _live_sockets map before calling + # listen/dial so that no callbacks are called before the socket is + # added to the map (because then the callback would fail!). + _live_sockets[id(self)] = self + if listen is not None: self.listen(listen) if dial is not None: self.dial(dial, block=block_on_dial) - _live_sockets[id(self)] = self - def dial(self, address, *, block=None): """Dial the specified address.