]> git.pld-linux.org Git - packages/rpm.git/blame - rpm-bug-146549.patch
- obsolete
[packages/rpm.git] / rpm-bug-146549.patch
CommitLineData
a14849de
ER
1https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=146549
2
3--- rpm-4.4.2/rpmio/rpmsq.c.deadlock 2005-07-13 12:47:03.000000000 +0200
4+++ rpm-4.4.2/rpmio/rpmsq.c 2005-08-19 14:47:53.000000000 +0200
5@@ -218,7 +218,6 @@
6
7 sq->id = ME();
8 ret = pthread_mutex_init(&sq->mutex, NULL);
9- ret = pthread_cond_init(&sq->cond, NULL);
10 insque(elem, (prev != NULL ? prev : rpmsqQueue));
11 ret = sigrelse(SIGCHLD);
12 }
13@@ -240,8 +239,11 @@
14 ret = sighold (SIGCHLD);
15 if (ret == 0) {
16 remque(elem);
17- ret = pthread_cond_destroy(&sq->cond);
18- ret = pthread_mutex_destroy(&sq->mutex);
19+
20+ /* Unlock the mutex and then destroy it */
21+ if((ret = pthread_mutex_unlock(&sq->mutex)) == 0)
22+ ret = pthread_mutex_destroy(&sq->mutex);
23+
24 sq->id = NULL;
25 /*@-bounds@*/
26 if (sq->pipes[1]) ret = close(sq->pipes[1]);
27@@ -315,11 +317,20 @@
28 sq != NULL && sq != rpmsqQueue;
29 sq = sq->q_forw)
30 {
31+ int ret;
32+
33 if (sq->child != reaped)
34 /*@innercontinue@*/ continue;
35 sq->reaped = reaped;
36 sq->status = status;
37- (void) pthread_cond_signal(&sq->cond);
38+
39+ /* Unlock the mutex. The waiter will then be able to
40+ * aquire the lock.
41+ *
42+ * XXX: jbj, wtd, if this fails?
43+ */
44+ ret = pthread_mutex_unlock(&sq->mutex);
45+
46 /*@innerbreak@*/ break;
47 }
48 }
49@@ -391,6 +402,7 @@
50 {
51 pid_t pid;
52 int xx;
53+ int nothreads = 0; /* XXX: Shouldn't this be a global? */
54
55 if (sq->reaper) {
56 xx = rpmsqInsert(sq, NULL);
57@@ -405,6 +417,24 @@
58
59 xx = sighold(SIGCHLD);
60
61+ /*
62+ * Initialize the cond var mutex. We have to aquire the lock we
63+ * use for the condition before we fork. Otherwise it is possible for
64+ * the child to exit, we get sigchild and the sig handler to send
65+ * the condition signal before we are waiting on the condition.
66+ */
67+ if (!nothreads) {
68+ if(pthread_mutex_lock(&sq->mutex)) {
69+ /* Yack we did not get the lock, lets just give up */
70+/*@-bounds@*/
71+ xx = close(sq->pipes[0]);
72+ xx = close(sq->pipes[1]);
73+ sq->pipes[0] = sq->pipes[1] = -1;
74+/*@=bounds@*/
75+ goto out;
76+ }
77+ }
78+
79 pid = fork();
80 if (pid < (pid_t) 0) { /* fork failed. */
81 /*@-bounds@*/
82@@ -462,10 +492,6 @@
83 /* Protect sq->reaped from handler changes. */
84 ret = sighold(SIGCHLD);
85
86- /* Initialize the cond var mutex. */
87- if (!nothreads)
88- ret = pthread_mutex_lock(&sq->mutex);
89-
90 /* Start the child, linux often runs child before parent. */
91 /*@-bounds@*/
92 if (sq->pipes[0] >= 0)
93@@ -486,7 +512,13 @@
94 ret = sigpause(SIGCHLD);
95 else {
96 xx = sigrelse(SIGCHLD);
97- ret = pthread_cond_wait(&sq->cond, &sq->mutex);
98+
99+ /*
100+ * We start before the fork with this mutex locked;
101+ * The only one that unlocks this the signal handler.
102+ * So if we get the lock the child has been reaped.
103+ */
104+ ret = pthread_mutex_lock(&sq->mutex);
105 xx = sighold(SIGCHLD);
106 }
107 }
108@@ -495,9 +527,6 @@
109 /* Accumulate stopwatch time spent waiting, potential performance gain. */
110 sq->ms_scriptlets += rpmswExit(&sq->op, -1)/1000;
111
112- /* Tear down cond var mutex, our child has been reaped. */
113- if (!nothreads)
114- xx = pthread_mutex_unlock(&sq->mutex);
115 xx = sigrelse(SIGCHLD);
116
117 #ifdef _RPMSQ_DEBUG
This page took 0.041634 seconds and 4 git commands to generate.