From 9711d1edcf92386d1e1ecd7c5f45b315391b3430 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 22 Apr 2014 09:42:14 -0400 Subject: [PATCH] Fix mass thread initialization of sessions There was a problem where the io thread could exist, but not yet be ready. Fix this by adding an iothreadready bool and a list of events to fire when iothread is ready. Change-Id: I4eb13e2210fa07bddbe717f56b12c736c99938dc --- pyghmi/ipmi/private/session.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pyghmi/ipmi/private/session.py b/pyghmi/ipmi/private/session.py index 8737854a..ac440d07 100644 --- a/pyghmi/ipmi/private/session.py +++ b/pyghmi/ipmi/private/session.py @@ -43,6 +43,8 @@ iothread = None # the thread in which all IO will be performed # This thread will tuck away the threading situation such that # calling code doesn't have to do any gymnastics to cope with # the nature of things. +iothreadready = False # whether io thread is yet ready to work +iothreadwaiters = [] # threads waiting for iothreadready ioqueue = collections.deque([]) selectbreak = None selectdeadline = 0 @@ -50,7 +52,8 @@ running = True iosockets = [] # set of iosockets that will be shared amongst Session objects -def _ioworker(initialized): +def _ioworker(): + global iothreadready global selectbreak global selectdeadline selectbreak = os.pipe() @@ -58,8 +61,11 @@ def _ioworker(initialized): iosockets.append(selectbreak[0]) iowaiters = [] timeout = 300 - initialized.set() + iothreadready = True while running: + while iothreadwaiters: + waiter = iothreadwaiters.pop() + waiter.set() if timeout < 0: timeout = 0 selectdeadline = _monotonic_time() + timeout @@ -230,13 +236,19 @@ class Session(object): def _createsocket(cls): global iowork global iothread + global iothreadready global iosockets if iothread is None: initevt = threading.Event() - iothread = threading.Thread(target=_ioworker, args=(initevt,)) + iothreadwaiters.append(initevt) + iothread = threading.Thread(target=_ioworker) iothread.daemon = True iothread.start() initevt.wait() + elif not iothreadready: + initevt = threading.Event() + iothreadwaiters.append(initevt) + initevt.wait() atexit.register(cls._cleanup) cls.socket = _io_apply(socket.socket, (socket.AF_INET6, socket.SOCK_DGRAM)) # INET6