URL: https://github.com/freeipa/freeipa/pull/309
Author: tomaskrizek
 Title: #309: ipa-replica-conncheck: fix race condition
Action: opened

PR body:
"""
When the thread that opens ports would execute notify() before the
original thread could call wait(), the original thread would wait
indefinitely for a notify() call.

https://fedorahosted.org/freeipa/ticket/6487
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/309/head:pr309
git checkout pr309
From 48e074f90fa21ccb42d055e532bd437bdf1c12da Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkri...@redhat.com>
Date: Mon, 5 Dec 2016 14:01:01 +0100
Subject: [PATCH] ipa-replica-conncheck: fix race condition

When the thread that opens ports would execute notify() before the
original thread could call wait(), the original thread would wait
indefinitely for a notify() call.

https://fedorahosted.org/freeipa/ticket/6487
---
 install/tools/ipa-replica-conncheck | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 121f068..cd1b138 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -297,16 +297,18 @@ class PortResponder(threading.Thread):
         self._close = False
         self._close_lock = threading.Lock()
         self.responder_data = 'FreeIPA'
-        self.ports_open = threading.Condition()
+        self.ports_opened = False
+        self.ports_open_cond = threading.Condition()
 
     def run(self):
         root_logger.debug('Starting listening thread.')
 
         for port in self.ports:
             self._bind_to_port(port.port, port.port_type)
-        with self.ports_open:
+        with self.ports_open_cond:
+            self.ports_opened = True
             root_logger.debug('Ports opened, notify original thread')
-            self.ports_open.notify()
+            self.ports_open_cond.notify()
 
         while not self._is_closing():
             ready_socks, _socks1, _socks2 = select.select(
@@ -462,9 +464,12 @@ def main():
 
         RESPONDER = PortResponder(required_ports)
         RESPONDER.start()
-        with RESPONDER.ports_open:
-            RESPONDER.ports_open.wait()
-            root_logger.debug('Original thread resumed')
+
+        with RESPONDER.ports_open_cond:
+            if not RESPONDER.ports_opened:
+                root_logger.debug('Original thread stopped')
+                RESPONDER.ports_open_cond.wait()
+                root_logger.debug('Original thread resumed')
 
         remote_check_opts = ['--replica %s' % options.hostname]
 
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to