diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2016-12-13 11:19:03 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2016-12-13 11:19:03 +0200 |
commit | 8cc3342cff0ef5721cda720809066a9ee4cb17eb (patch) | |
tree | 2c88d03e408b64c3ca1b7f16c94c49ebc18e4bbf | |
parent | 9b9e998c9afe33a5e2552ec03d33e13a22215394 (diff) | |
download | rpm-8cc3342cff0ef5721cda720809066a9ee4cb17eb.tar.gz |
Clean up rpmdb leftovers from an atexit() handler.
There's a standard C mechanism for cleaning up cruft at exit and
it's known as atexit handler. atexit() handlers do not get called
when exiting due to signal, but we're trapping the signals and calling
exit() voluntarily in that case so... for fsck's sake Sherlock.
This removes rpmdbCheckTerminate() from the API, the semantics
change incompatibly here and it makes even less sense after this.
It's a good time for this change since we're removing all sorts of
other goo out from the API as well.
Also rip out the previous workarounds from python side, RIP.
-rw-r--r-- | lib/misc.h | 2 | ||||
-rw-r--r-- | lib/rpmdb.c | 44 | ||||
-rw-r--r-- | lib/rpmdb.h | 10 | ||||
-rw-r--r-- | lib/rpmrc.c | 9 | ||||
-rw-r--r-- | python/rpmmodule.c | 15 | ||||
-rw-r--r-- | python/rpmts-py.c | 1 |
6 files changed, 34 insertions, 47 deletions
diff --git a/lib/misc.h b/lib/misc.h index fcd258438..74e94a2e7 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -62,6 +62,8 @@ RPM_GNUC_INTERNAL void rpmRelocationBuild(Header h, rpmRelocation *rawrelocs, int *rnrelocs, rpmRelocation **rrelocs, uint8_t **rbadrelocs); +RPM_GNUC_INTERNAL +void rpmAtExit(void); #ifdef __cplusplus } #endif diff --git a/lib/rpmdb.c b/lib/rpmdb.c index c6718ab43..545e0517c 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -33,6 +33,7 @@ #include "lib/fprint.h" #include "lib/header_internal.h" /* XXX for headerSetInstance() */ #include "lib/backend/dbiset.h" +#include "lib/misc.h" #include "debug.h" #undef HASHTYPE @@ -310,12 +311,26 @@ static rpmdb rpmdbRock; static rpmdbMatchIterator rpmmiRock; static rpmdbIndexIterator rpmiiRock; -int rpmdbCheckTerminate(int terminate) +void rpmAtExit(void) { - sigset_t newMask, oldMask; - static int terminating = 0; + rpmdb db; + rpmdbMatchIterator mi; + rpmdbIndexIterator ii; - if (terminating) return 0; + while ((mi = rpmmiRock) != NULL) + rpmdbFreeIterator(mi); + + while ((ii = rpmiiRock) != NULL) + rpmdbIndexIteratorFree(ii); + + while ((db = rpmdbRock) != NULL) + (void) rpmdbClose(db); +} + +static int rpmdbCheckTerminate(void) +{ + sigset_t newMask, oldMask; + int terminating = 0; (void) sigfillset(&newMask); /* block all signals */ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); @@ -324,31 +339,18 @@ int rpmdbCheckTerminate(int terminate) || rpmsqIsCaught(SIGQUIT) > 0 || rpmsqIsCaught(SIGHUP) > 0 || rpmsqIsCaught(SIGTERM) > 0 - || rpmsqIsCaught(SIGPIPE) > 0 - || terminate) + || rpmsqIsCaught(SIGPIPE) > 0) terminating = 1; - if (terminating) { - rpmdb db; - rpmdbMatchIterator mi; - rpmdbIndexIterator ii; - - while ((mi = rpmmiRock) != NULL) - rpmdbFreeIterator(mi); - - while ((ii = rpmiiRock) != NULL) - rpmdbIndexIteratorFree(ii); - - while ((db = rpmdbRock) != NULL) - (void) rpmdbClose(db); - } sigprocmask(SIG_SETMASK, &oldMask, NULL); return terminating; } int rpmdbCheckSignals(void) { - if (rpmdbCheckTerminate(0)) { + static int terminating = 0; + if (!terminating && rpmdbCheckTerminate()) { + terminating = 1; rpmlog(RPMLOG_DEBUG, "Exiting on signal...\n"); exit(EXIT_FAILURE); } diff --git a/lib/rpmdb.h b/lib/rpmdb.h index 122cbd040..3a782738b 100644 --- a/lib/rpmdb.h +++ b/lib/rpmdb.h @@ -151,16 +151,6 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi); int rpmdbCheckSignals(void); /** \ingroup rpmdb - * Check rpmdb signal handler for trapped signal and/or requested exit, - * clean up any open iterators and databases on termination condition. - * On non-zero exit any open references to rpmdb are invalid and cannot - * be accessed anymore, calling process should terminate immediately. - * @param terminate 0 to only check for signals, 1 to terminate anyway - * @return 0 to continue, 1 if termination cleanup was done. - */ -int rpmdbCheckTerminate(int terminate); - -/** \ingroup rpmdb * Destroy rpm database iterator. * @param mi rpm database iterator * @return NULL always diff --git a/lib/rpmrc.c b/lib/rpmrc.c index 7d67e6c46..4ed991321 100644 --- a/lib/rpmrc.c +++ b/lib/rpmrc.c @@ -1602,13 +1602,22 @@ exit: return rc; } +static void register_atexit(void) +{ + if (atexit(rpmAtExit) != 0) + rpmlog(RPMLOG_WARNING, _("failed to register exit handler")); +} + /* External interfaces */ int rpmReadConfigFiles(const char * file, const char * target) { + static pthread_once_t atexit_registered = PTHREAD_ONCE_INIT; int rc = -1; /* assume failure */ rpmrcCtx ctx = rpmrcCtxAcquire(1); + pthread_once(&atexit_registered, register_atexit); + /* Force preloading of dlopen()'ed libraries in case we go chrooting */ if (rpmugInit()) goto exit; diff --git a/python/rpmmodule.c b/python/rpmmodule.c index a708563bd..6f4a6f3ed 100644 --- a/python/rpmmodule.c +++ b/python/rpmmodule.c @@ -208,14 +208,6 @@ static PyMethodDef rpmModuleMethods[] = { { NULL } } ; -/* -* Force clean up of open iterators and dbs on exit. -*/ -static void rpm_exithook(void) -{ - rpmdbCheckTerminate(1); -} - static char rpm__doc__[] = ""; /* @@ -327,13 +319,6 @@ static int initModule(PyObject *m) { PyObject * d; - /* - * treat error to register rpm cleanup hook as fatal, tracebacks - * can and will leave stale locks around if we can't clean up - */ - if (Py_AtExit(rpm_exithook) == -1) - return 0; - /* failure to initialize rpm (crypto and all) is rather fatal too... */ if (rpmReadConfigFiles(NULL, NULL) == -1) return 0; diff --git a/python/rpmts-py.c b/python/rpmts-py.c index f05371c5e..d56a09c22 100644 --- a/python/rpmts-py.c +++ b/python/rpmts-py.c @@ -167,7 +167,6 @@ static void die(PyObject *cb) } fprintf(stderr, "FATAL ERROR: python callback %s failed, aborting!\n", pyfn ? pyfn : "???"); - rpmdbCheckTerminate(1); exit(EXIT_FAILURE); } |