1 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=146549
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
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);
14 ret = sighold (SIGCHLD);
17 - ret = pthread_cond_destroy(&sq->cond);
18 - ret = pthread_mutex_destroy(&sq->mutex);
20 + /* Unlock the mutex and then destroy it */
21 + if((ret = pthread_mutex_unlock(&sq->mutex)) == 0)
22 + ret = pthread_mutex_destroy(&sq->mutex);
26 if (sq->pipes[1]) ret = close(sq->pipes[1]);
28 sq != NULL && sq != rpmsqQueue;
33 if (sq->child != reaped)
34 /*@innercontinue@*/ continue;
37 - (void) pthread_cond_signal(&sq->cond);
39 + /* Unlock the mutex. The waiter will then be able to
42 + * XXX: jbj, wtd, if this fails?
44 + ret = pthread_mutex_unlock(&sq->mutex);
46 /*@innerbreak@*/ break;
53 + int nothreads = 0; /* XXX: Shouldn't this be a global? */
56 xx = rpmsqInsert(sq, NULL);
59 xx = sighold(SIGCHLD);
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.
68 + if(pthread_mutex_lock(&sq->mutex)) {
69 + /* Yack we did not get the lock, lets just give up */
71 + xx = close(sq->pipes[0]);
72 + xx = close(sq->pipes[1]);
73 + sq->pipes[0] = sq->pipes[1] = -1;
80 if (pid < (pid_t) 0) { /* fork failed. */
83 /* Protect sq->reaped from handler changes. */
84 ret = sighold(SIGCHLD);
86 - /* Initialize the cond var mutex. */
88 - ret = pthread_mutex_lock(&sq->mutex);
90 /* Start the child, linux often runs child before parent. */
92 if (sq->pipes[0] >= 0)
94 ret = sigpause(SIGCHLD);
96 xx = sigrelse(SIGCHLD);
97 - ret = pthread_cond_wait(&sq->cond, &sq->mutex);
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.
104 + ret = pthread_mutex_lock(&sq->mutex);
105 xx = sighold(SIGCHLD);
109 /* Accumulate stopwatch time spent waiting, potential performance gain. */
110 sq->ms_scriptlets += rpmswExit(&sq->op, -1)/1000;
112 - /* Tear down cond var mutex, our child has been reaped. */
114 - xx = pthread_mutex_unlock(&sq->mutex);
115 xx = sigrelse(SIGCHLD);