Source: MontaVista Software, Inc. Type: Defect Fix Disposition: merge to rpm.org Description: Cygwin appears to have issues w/ sending signals to blocked processes. This patch reverts the normal rpm asyncronous reaper processing with the "waitpid" approach. If any other systems experience deadlocked scriptlets, this might be a first approach at a workaround. Index: rpm-4.3.3/lib/psm.c =================================================================== --- rpm-4.3.3.orig/lib/psm.c +++ rpm-4.3.3/lib/psm.c @@ -536,7 +536,11 @@ if (progArgv == NULL && script == NULL) return rc; +#if !defined(__CYGWIN__) psm->sq.reaper = 1; +#else + psm->sq.reaper = 0; +#endif /* XXX FIXME: except for %verifyscript, rpmteNEVR can be used. */ xx = headerNVR(h, &n, &v, &r); @@ -697,6 +701,9 @@ int flag; int fdno; +if (_psm_debug) +fprintf(stderr, "--> psm runScript %s\n", argv[0]); + pipes[0] = pipes[1] = 0; /* make stdin inaccessible */ xx = pipe(pipes); Index: rpm-4.3.3/rpmio/rpmsq.c =================================================================== --- rpm-4.3.3.orig/rpmio/rpmsq.c +++ rpm-4.3.3/rpmio/rpmsq.c @@ -392,7 +392,6 @@ { pid_t pid; int xx; - int nothreads = 0; /* XXX: Shouldn't this be a global? */ if (sq->reaper) { xx = rpmsqInsert(sq, NULL); @@ -401,9 +400,15 @@ fprintf(stderr, " Enable(%p): %p\n", ME(), sq); #endif xx = rpmsqEnable(SIGCHLD, NULL); - } - xx = pipe(sq->pipes); + xx = pipe(sq->pipes); + } else { + /* Reset the contents of sq! */ + /* rpmsqInsert normally does this */ + sq->child = 0; + sq->reaped = 0; + sq->status = 0; + } xx = sighold(SIGCHLD); @@ -413,7 +418,7 @@ * 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 (sq->reaper) { if(pthread_mutex_lock(&sq->mutex)) { /* Yack we did not get the lock, lets just give up */ /*@-bounds@*/ @@ -428,20 +433,24 @@ pid = fork(); if (pid < (pid_t) 0) { /* fork failed. */ /*@-bounds@*/ - xx = close(sq->pipes[0]); - xx = close(sq->pipes[1]); - sq->pipes[0] = sq->pipes[1] = -1; + if (sq->reaper) { + xx = close(sq->pipes[0]); + xx = close(sq->pipes[1]); + sq->pipes[0] = sq->pipes[1] = -1; + } /*@=bounds@*/ goto out; } else if (pid == (pid_t) 0) { /* Child. */ int yy; + if (sq->reaper) { /* Block to permit parent time to wait. */ /*@-bounds@*/ - xx = close(sq->pipes[1]); - xx = read(sq->pipes[0], &yy, sizeof(yy)); - xx = close(sq->pipes[0]); - sq->pipes[0] = sq->pipes[1] = -1; + xx = close(sq->pipes[1]); + xx = read(sq->pipes[0], &yy, sizeof(yy)); + xx = close(sq->pipes[0]); + sq->pipes[0] = sq->pipes[1] = -1; + } /*@=bounds@*/ #ifdef _RPMSQ_DEBUG @@ -475,7 +484,6 @@ /*@globals fileSystem, internalState @*/ /*@modifies sq, fileSystem, internalState @*/ { - int nothreads = 0; int ret = 0; int xx; @@ -497,10 +505,7 @@ /* Wait for handler to receive SIGCHLD. */ /*@-infloops@*/ while (ret == 0 && sq->reaped != sq->child) { - if (nothreads) - /* Note that sigpause re-enables SIGCHLD. */ - ret = sigpause(SIGCHLD); - else { + if (sq->reaper) { xx = sigrelse(SIGCHLD); /* @@ -510,7 +515,9 @@ */ ret = pthread_mutex_lock(&sq->mutex); xx = sighold(SIGCHLD); - } + } else + /* Note that sigpause re-enables SIGCHLD. */ + ret = sigpause(SIGCHLD); } /*@=infloops@*/ @@ -553,6 +560,7 @@ do { reaped = waitpid(sq->child, &status, 0); } while (reaped >= 0 && reaped != sq->child); +assert(!(reaped == -1 && errno == ECHILD)); sq->reaped = reaped; sq->status = status; #ifdef _RPMSQ_DEBUG