Author: glen Date: Wed Apr 26 22:04:59 2006 GMT Module: SOURCES Tag: HEAD ---- Log message: - lockup fix
---- Files affected: SOURCES: rpm-bug-146549.patch (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/rpm-bug-146549.patch diff -u /dev/null SOURCES/rpm-bug-146549.patch:1.1 --- /dev/null Thu Apr 27 00:04:59 2006 +++ SOURCES/rpm-bug-146549.patch Thu Apr 27 00:04:54 2006 @@ -0,0 +1,117 @@ +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=146549 + +--- rpm-4.4.2/rpmio/rpmsq.c.deadlock 2005-07-13 12:47:03.000000000 +0200 ++++ rpm-4.4.2/rpmio/rpmsq.c 2005-08-19 14:47:53.000000000 +0200 +@@ -218,7 +218,6 @@ + + sq->id = ME(); + ret = pthread_mutex_init(&sq->mutex, NULL); +- ret = pthread_cond_init(&sq->cond, NULL); + insque(elem, (prev != NULL ? prev : rpmsqQueue)); + ret = sigrelse(SIGCHLD); + } +@@ -240,8 +239,11 @@ + ret = sighold (SIGCHLD); + if (ret == 0) { + remque(elem); +- ret = pthread_cond_destroy(&sq->cond); +- ret = pthread_mutex_destroy(&sq->mutex); ++ ++ /* Unlock the mutex and then destroy it */ ++ if((ret = pthread_mutex_unlock(&sq->mutex)) == 0) ++ ret = pthread_mutex_destroy(&sq->mutex); ++ + sq->id = NULL; + /[EMAIL PROTECTED]@*/ + if (sq->pipes[1]) ret = close(sq->pipes[1]); +@@ -315,11 +317,20 @@ + sq != NULL && sq != rpmsqQueue; + sq = sq->q_forw) + { ++ int ret; ++ + if (sq->child != reaped) + /[EMAIL PROTECTED]@*/ continue; + sq->reaped = reaped; + sq->status = status; +- (void) pthread_cond_signal(&sq->cond); ++ ++ /* Unlock the mutex. The waiter will then be able to ++ * aquire the lock. ++ * ++ * XXX: jbj, wtd, if this fails? ++ */ ++ ret = pthread_mutex_unlock(&sq->mutex); ++ + /[EMAIL PROTECTED]@*/ break; + } + } +@@ -391,6 +402,7 @@ + { + pid_t pid; + int xx; ++ int nothreads = 0; /* XXX: Shouldn't this be a global? */ + + if (sq->reaper) { + xx = rpmsqInsert(sq, NULL); +@@ -405,6 +417,24 @@ + + xx = sighold(SIGCHLD); + ++ /* ++ * Initialize the cond var mutex. We have to aquire the lock we ++ * use for the condition before we fork. Otherwise it is possible for ++ * the child to exit, we get sigchild and the sig handler to send ++ * the condition signal before we are waiting on the condition. ++ */ ++ if (!nothreads) { ++ if(pthread_mutex_lock(&sq->mutex)) { ++ /* Yack we did not get the lock, lets just give up */ ++/[EMAIL PROTECTED]@*/ ++ xx = close(sq->pipes[0]); ++ xx = close(sq->pipes[1]); ++ sq->pipes[0] = sq->pipes[1] = -1; ++/[EMAIL PROTECTED]@*/ ++ goto out; ++ } ++ } ++ + pid = fork(); + if (pid < (pid_t) 0) { /* fork failed. */ + /[EMAIL PROTECTED]@*/ +@@ -462,10 +492,6 @@ + /* Protect sq->reaped from handler changes. */ + ret = sighold(SIGCHLD); + +- /* Initialize the cond var mutex. */ +- if (!nothreads) +- ret = pthread_mutex_lock(&sq->mutex); +- + /* Start the child, linux often runs child before parent. */ + /[EMAIL PROTECTED]@*/ + if (sq->pipes[0] >= 0) +@@ -486,7 +512,13 @@ + ret = sigpause(SIGCHLD); + else { + xx = sigrelse(SIGCHLD); +- ret = pthread_cond_wait(&sq->cond, &sq->mutex); ++ ++ /* ++ * We start before the fork with this mutex locked; ++ * The only one that unlocks this the signal handler. ++ * So if we get the lock the child has been reaped. ++ */ ++ ret = pthread_mutex_lock(&sq->mutex); + xx = sighold(SIGCHLD); + } + } +@@ -495,9 +527,6 @@ + /* Accumulate stopwatch time spent waiting, potential performance gain. */ + sq->ms_scriptlets += rpmswExit(&sq->op, -1)/1000; + +- /* Tear down cond var mutex, our child has been reaped. */ +- if (!nothreads) +- xx = pthread_mutex_unlock(&sq->mutex); + xx = sigrelse(SIGCHLD); + + #ifdef _RPMSQ_DEBUG ================================================================ _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit