[createrepo/f17] Fix the deadlock issue. BZ 856363

Zdeněk Pavlas zpavlas at fedoraproject.org
Thu Feb 28 14:52:05 UTC 2013


commit af9b91b86c3f875984bfcf15a721910016621887
Author: Zdenek Pavlas <zpavlas at redhat.com>
Date:   Thu Feb 28 13:52:16 2013 +0100

    Fix the deadlock issue.  BZ 856363

 BZ-856363-fix-deadlock.patch |   64 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)
---
diff --git a/BZ-856363-fix-deadlock.patch b/BZ-856363-fix-deadlock.patch
new file mode 100644
index 0000000..ba05428
--- /dev/null
+++ b/BZ-856363-fix-deadlock.patch
@@ -0,0 +1,64 @@
+commit 71cd4c45a84366ae66eb1b6e619f1b3987249c2d
+Author: Zdeněk Pavlas <zpavlas at redhat.com>
+Date:   Wed Sep 12 12:36:49 2012 +0200
+
+    Fix the deadlock issue.  BZ 856363
+    
+    select() on all workers, process their output.
+    Exit loop when all pipes have been closed.
+
+diff --git a/createrepo/__init__.py b/createrepo/__init__.py
+index d2e2039..e132257 100644
+--- a/createrepo/__init__.py
++++ b/createrepo/__init__.py
+@@ -26,6 +26,7 @@ import tempfile
+ import stat
+ import fcntl
+ import subprocess
++from select import select
+ 
+ from yum import misc, Errors
+ from yum.repoMDObject import RepoMD, RepoData
+@@ -650,6 +651,7 @@ class MetaDataGenerator:
+             
+                 
+ 
++            fds = {}
+             for (num, cmdline) in worker_cmd_dict.items():
+                 if not self.conf.quiet:
+                     self.callback.log("Spawning worker %s with %s pkgs" % (num, 
+@@ -657,22 +659,20 @@ class MetaDataGenerator:
+                 job = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
+                                         stderr=subprocess.PIPE)
+                 worker_jobs[num] = job
++                fds[job.stdout.fileno()] = num, job.stdout, self.callback.log
++                fds[job.stderr.fileno()] = num, job.stderr, self.callback.errorlog
+             
+-            gimmebreak = 0
+-            while gimmebreak != len(worker_jobs.keys()):
+-                gimmebreak = 0
+-                for (num,job) in worker_jobs.items():
+-                    if job.poll() is not None:
+-                        gimmebreak+=1
+-                    line = job.stdout.readline()
+-                    if line:
+-                        self.callback.log('Worker %s: %s' % (num, line.rstrip()))
+-                    line = job.stderr.readline()
+-                    if line:
+-                        self.callback.errorlog('Worker %s: %s' % (num, line.rstrip()))
+-                    
++            while fds:
++                for fd in select(fds, [], [])[0]:
++                    num, stream, logger = fds[fd]
++                    line = stream.readline()
++                    if line == '':
++                        del fds[fd]
++                        continue
++                    logger('Worker %s: %s' % (num, line.rstrip()))
++
+             for (num, job) in worker_jobs.items():
+-                if job.returncode != 0:
++                if job.wait() != 0:
+                     msg = "Worker exited with non-zero value: %s. Fatal." % job.returncode
+                     self.callback.errorlog(msg)
+                     raise MDError, msg


More information about the scm-commits mailing list