diff --git a/lib/backend/dbi.hh b/lib/backend/dbi.hh index b21667ce67..1fb86017e9 100644 --- a/lib/backend/dbi.hh +++ b/lib/backend/dbi.hh @@ -4,6 +4,7 @@ #include #include +#include #include "dbiset.hh" #include @@ -68,7 +69,7 @@ struct rpmdb_s { struct rpmop_s db_putops; struct rpmop_s db_delops; - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ }; /* Type of the dbi, also serves as the join key size */ diff --git a/lib/header.cc b/lib/header.cc index d0eb3ad36b..ea017fa0cc 100644 --- a/lib/header.cc +++ b/lib/header.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include "header_internal.hh" @@ -109,7 +110,7 @@ struct headerToken_s { unsigned int instance; /*!< Rpmdb instance */ headerFlags flags; int sorted; /*!< Current sort method */ - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ }; /** \ingroup header @@ -239,18 +240,9 @@ Header headerLink(Header h) return h; } -static Header headerUnlink(Header h) -{ - if (h != NULL) - h->nrefs--; - return NULL; -} - Header headerFree(Header h) { - (void) headerUnlink(h); - - if (h == NULL || h->nrefs > 0) + if (h == NULL || --h->nrefs > 0) return NULL; if (h->index) { diff --git a/lib/psm.cc b/lib/psm.cc index 9afbe750e5..655e5b9a4f 100644 --- a/lib/psm.cc +++ b/lib/psm.cc @@ -6,6 +6,7 @@ #include "system.h" #include +#include #include /* rpmvercmp and others */ #include @@ -43,7 +44,7 @@ struct rpmpsm_s { rpm_loff_t amount; /*!< Callback amount. */ rpm_loff_t total; /*!< Callback total. */ - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ }; static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal); diff --git a/lib/rpmdb.cc b/lib/rpmdb.cc index 410f71bcbb..419cb4517e 100644 --- a/lib/rpmdb.cc +++ b/lib/rpmdb.cc @@ -43,8 +43,6 @@ using std::unordered_map; using std::vector; -static rpmdb rpmdbUnlink(rpmdb db); - static int buildIndexes(rpmdb db) { int rc = 0; @@ -346,12 +344,7 @@ int rpmdbClose(rpmdb db) { int rc = 0; - if (db == NULL) - goto exit; - - (void) rpmdbUnlink(db); - - if (db->nrefs > 0) + if (db == NULL || --db->nrefs > 0) goto exit; /* Always re-enable fsync on close of rw-database */ @@ -462,13 +455,6 @@ static int openDatabase(const char * prefix, return rc; } -static rpmdb rpmdbUnlink(rpmdb db) -{ - if (db) - db->nrefs--; - return NULL; -} - rpmdb rpmdbLink(rpmdb db) { if (db) diff --git a/lib/rpmds.cc b/lib/rpmds.cc index 4f791c7573..518231174e 100644 --- a/lib/rpmds.cc +++ b/lib/rpmds.cc @@ -2,6 +2,7 @@ * \file lib/rpmds.c */ #include "system.h" +#include #include #include /* rpmvercmp */ @@ -29,7 +30,7 @@ struct rpmds_s { int32_t Count; /*!< No. of elements */ unsigned int instance; /*!< From rpmdb instance? */ int i; /*!< Element index. */ - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ int *ti; /*!< Trigger index. */ }; @@ -202,12 +203,6 @@ rpm_color_t rpmdsColorIndex(rpmds ds, int i) Color = ds->Color[i]; return Color; } -static rpmds rpmdsUnlink(rpmds ds) -{ - if (ds) - ds->nrefs--; - return NULL; -} rpmds rpmdsLink(rpmds ds) { @@ -220,12 +215,9 @@ rpmds rpmdsFree(rpmds ds) { rpmTagVal tagEVR, tagF, tagTi; - if (ds == NULL) + if (ds == NULL || --ds->nrefs > 0) return NULL; - if (ds->nrefs > 1) - return rpmdsUnlink(ds); - if (dsType(ds->tagN, NULL, &tagEVR, &tagF, &tagTi)) return NULL; @@ -240,7 +232,6 @@ rpmds rpmdsFree(rpmds ds) ds->DNEVR = _free(ds->DNEVR); ds->Color = _free(ds->Color); - (void) rpmdsUnlink(ds); delete ds; return NULL; } diff --git a/lib/rpmfi.cc b/lib/rpmfi.cc index 5785951afc..d5d7bde6f0 100644 --- a/lib/rpmfi.cc +++ b/lib/rpmfi.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,7 @@ struct rpmfi_s { rpmfiles files; /*!< File info set */ rpmcpio_t archive; /*!< Archive with payload */ uint8_t * found; /*!< Bit field of files found in the archive */ - int nrefs; /*!< Reference count */ + std::atomic_int nrefs; /*!< Reference count */ }; struct rpmfn_s { @@ -122,19 +123,12 @@ struct rpmfiles_s { nlinkHash *nlinks; /*!< Files connected by hardlinks */ rpm_loff_t * replacedSizes; /*!< (TR_ADDED) */ int magic; - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ }; static int indexSane(rpmtd xd, rpmtd yd, rpmtd zd); static int cmpPoolFn(rpmstrPool pool, rpmfn files, int ix, const char * fn); -static rpmfiles rpmfilesUnlink(rpmfiles fi) -{ - if (fi) - fi->nrefs--; - return NULL; -} - rpmfiles rpmfilesLink(rpmfiles fi) { if (fi) @@ -142,13 +136,6 @@ rpmfiles rpmfilesLink(rpmfiles fi) return fi; } -static rpmfi rpmfiUnlink(rpmfi fi) -{ - if (fi) - fi->nrefs--; - return NULL; -} - rpmfi rpmfiLink(rpmfi fi) { if (fi) @@ -1240,10 +1227,8 @@ int rpmfilesConfigConflict(rpmfiles fi, int ix) rpmfiles rpmfilesFree(rpmfiles fi) { - if (fi == NULL) return NULL; - - if (fi->nrefs > 1) - return rpmfilesUnlink(fi); + if (fi == NULL || --fi->nrefs > 0) + return NULL; if (rpmfilesFC(fi) > 0) { if (fi->ofndata != &fi->fndata) { @@ -1297,7 +1282,6 @@ rpmfiles rpmfilesFree(rpmfiles fi) delete fi->nlinks; - (void) rpmfilesUnlink(fi); delete fi; return NULL; @@ -1305,10 +1289,8 @@ rpmfiles rpmfilesFree(rpmfiles fi) rpmfi rpmfiFree(rpmfi fi) { - if (fi == NULL) return NULL; - - if (fi->nrefs > 1) - return rpmfiUnlink(fi); + if (fi == NULL || --fi->nrefs > 0) + return NULL; fi->files = rpmfilesFree(fi->files); fi->fn = _free(fi->fn); diff --git a/lib/rpmprob.cc b/lib/rpmprob.cc index 4f604c5675..cabfaf785f 100644 --- a/lib/rpmprob.cc +++ b/lib/rpmprob.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -19,11 +20,9 @@ struct rpmProblem_s { rpmProblemType type; char * str1; uint64_t num1; - int nrefs; + std::atomic_int nrefs; }; -static rpmProblem rpmProblemUnlink(rpmProblem prob); - rpmProblem rpmProblemCreate(rpmProblemType type, const char * pkgNEVR, fnpyKey key, const char * altNEVR, @@ -44,11 +43,9 @@ rpmProblem rpmProblemCreate(rpmProblemType type, rpmProblem rpmProblemFree(rpmProblem prob) { - if (prob == NULL) return NULL; + if (prob == NULL || --prob->nrefs > 0) + return NULL; - if (prob->nrefs > 1) { - return rpmProblemUnlink(prob); - } prob->pkgNEVR = _free(prob->pkgNEVR); prob->altNEVR = _free(prob->altNEVR); prob->str1 = _free(prob->str1); @@ -64,14 +61,6 @@ rpmProblem rpmProblemLink(rpmProblem prob) return prob; } -static rpmProblem rpmProblemUnlink(rpmProblem prob) -{ - if (prob) { - prob->nrefs--; - } - return NULL; -} - const char * rpmProblemGetPkgNEVR(rpmProblem p) { return (p->pkgNEVR); diff --git a/lib/rpmps.cc b/lib/rpmps.cc index d26f5f4811..0dd5c6713e 100644 --- a/lib/rpmps.cc +++ b/lib/rpmps.cc @@ -5,7 +5,7 @@ #include "system.h" #include - +#include #include #include @@ -18,7 +18,7 @@ using std::vector; struct rpmps_s { vector probs; /*!< Array of pointers to specific problems. */ - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ }; struct rpmpsi_s { @@ -27,14 +27,6 @@ struct rpmpsi_s { }; -static rpmps rpmpsUnlink(rpmps ps) -{ - if (ps) { - ps->nrefs--; - } - return NULL; -} - rpmps rpmpsLink(rpmps ps) { if (ps) { @@ -65,7 +57,7 @@ rpmpsi rpmpsInitIterator(rpmps ps) rpmpsi rpmpsFreeIterator(rpmpsi psi) { if (psi != NULL) { - rpmpsUnlink(psi->ps); + rpmpsFree(psi->ps); delete psi; } return NULL; @@ -107,10 +99,8 @@ rpmps rpmpsCreate(void) rpmps rpmpsFree(rpmps ps) { - if (ps == NULL) return NULL; - if (ps->nrefs > 1) { - return rpmpsUnlink(ps); - } + if (ps == NULL || --ps->nrefs > 0) + return NULL; for (auto & prob : ps->probs) rpmProblemFree(prob); diff --git a/lib/rpmts.cc b/lib/rpmts.cc index 6ba46a7c1b..be28a4e1b9 100644 --- a/lib/rpmts.cc +++ b/lib/rpmts.cc @@ -60,13 +60,6 @@ static void loadKeyring(rpmts ts); int _rpmts_stats = 0; -static rpmts rpmtsUnlink(rpmts ts) -{ - if (ts) - ts->nrefs--; - return NULL; -} - rpmts rpmtsLink(rpmts ts) { if (ts) @@ -951,11 +944,11 @@ static void rpmtsPrintStats(rpmts ts) rpmts rpmtsFree(rpmts ts) { - if (ts == NULL) + if (ts == NULL || (--(ts->nrefs)) > 0) return NULL; - if (ts->nrefs > 1) - return rpmtsUnlink(ts); + /* Cleanup still needs to rpmtsLink() and rpmtsFree() */ + ts = rpmtsLink(ts); /* Don't issue element change callbacks when freeing */ rpmtsSetChangeCallback(ts, NULL, NULL); @@ -984,7 +977,6 @@ rpmts rpmtsFree(rpmts ts) if (_rpmts_stats) rpmtsPrintStats(ts); - (void) rpmtsUnlink(ts); delete ts; return NULL; @@ -1403,7 +1395,6 @@ rpm_time_t rpmtsGetTime(rpmts ts, time_t step) rpmtsi rpmtsiFree(rpmtsi tsi) { - /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */ if (tsi) { tsi->ts = rpmtsFree(tsi->ts); delete tsi; diff --git a/lib/rpmts_internal.hh b/lib/rpmts_internal.hh index c75def22e6..ded10ec092 100644 --- a/lib/rpmts_internal.hh +++ b/lib/rpmts_internal.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -92,7 +93,7 @@ struct rpmts_s { rpmPlugins plugins; /*!< Transaction plugins */ - int nrefs; /*!< Reference count. */ + std::atomic_int nrefs; /*!< Reference count. */ rpmtriggers trigs2run; /*!< Transaction file triggers */ diff --git a/rpmio/rpmio.cc b/rpmio/rpmio.cc index 2131c03a11..77e6e7657e 100644 --- a/rpmio/rpmio.cc +++ b/rpmio/rpmio.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ typedef struct { * The FD_t File Handle data structure. */ struct FD_s { - int nrefs; + std::atomic_int nrefs; int flags; #define RPMIO_DEBUG_IO 0x40000000 int magic; @@ -322,17 +323,17 @@ FD_t fdLink(FD_t fd) FD_t fdFree( FD_t fd) { - if (fd) { - if (--fd->nrefs > 0) - return fd; - delete fd->stats; - if (fd->digests) { - fd->digests = rpmDigestBundleFree(fd->digests); - } - delete fd->fps; - free(fd->descr); - delete fd; + if (fd == NULL || --fd->nrefs > 0) + return fd; + + delete fd->stats; + if (fd->digests) { + fd->digests = rpmDigestBundleFree(fd->digests); } + delete fd->fps; + free(fd->descr); + delete fd; + return NULL; } diff --git a/rpmio/rpmkeyring.cc b/rpmio/rpmkeyring.cc index 0d8f922593..aa27ae04da 100644 --- a/rpmio/rpmkeyring.cc +++ b/rpmio/rpmkeyring.cc @@ -1,6 +1,7 @@ #include "system.h" #include +#include #include #include #include @@ -22,7 +23,7 @@ struct rpmPubkey_s { std::string keyid; rpmPubkey primarykey; pgpDigParams pgpkey; - int nrefs; + std::atomic_int nrefs; std::shared_mutex mutex; }; @@ -31,7 +32,7 @@ using rdlock = std::shared_lock; struct rpmKeyring_s { std::map keys; /* pointers to keys */ - int nrefs; + std::atomic_int nrefs; std::shared_mutex mutex; }; @@ -49,15 +50,13 @@ rpmKeyring rpmKeyringNew(void) rpmKeyring rpmKeyringFree(rpmKeyring keyring) { - if (keyring == NULL) + if (keyring == NULL || --keyring->nrefs > 0) return NULL; - wrlock lock(keyring->mutex); - if (--keyring->nrefs == 0) { - for (auto & item : keyring->keys) - rpmPubkeyFree(item.second); - delete keyring; - } + for (auto & item : keyring->keys) + rpmPubkeyFree(item.second); + delete keyring; + return NULL; } @@ -106,7 +105,6 @@ rpmPubkey rpmKeyringLookupKey(rpmKeyring keyring, rpmPubkey key) rpmKeyring rpmKeyringLink(rpmKeyring keyring) { if (keyring) { - wrlock lock(keyring->mutex); keyring->nrefs++; } return keyring; @@ -166,12 +164,6 @@ static rpmPubkey rpmPubkeyNewSubkey(rpmPubkey primarykey, pgpDigParams pgpkey) return key; } -static rpmPubkey pubkeyLink(rpmPubkey key) -{ - key->nrefs++; - return key; -} - rpmPubkey *rpmGetSubkeys(rpmPubkey primarykey, int *count) { rpmPubkey *subkeys = NULL; @@ -190,7 +182,7 @@ rpmPubkey *rpmGetSubkeys(rpmPubkey primarykey, int *count) subkeys = (rpmPubkey *)xmalloc(pgpsubkeysCount * sizeof(*subkeys)); for (i = 0; i < pgpsubkeysCount; i++) { subkeys[i] = rpmPubkeyNewSubkey(primarykey, pgpsubkeys[i]); - primarykey = pubkeyLink(primarykey); + primarykey = rpmPubkeyLink(primarykey); } free(pgpsubkeys); } @@ -206,7 +198,7 @@ rpmPubkey pubkeyPrimarykey(rpmPubkey key) if (key) { wrlock lock(key->mutex); if (key->primarykey == NULL) { - primarykey = pubkeyLink(key); + primarykey = rpmPubkeyLink(key); } else { primarykey = rpmPubkeyLink(key->primarykey); } @@ -242,22 +234,19 @@ char * rpmPubkeyFingerprintAsHex(rpmPubkey key) rpmPubkey rpmPubkeyFree(rpmPubkey key) { - if (key == NULL) + if (key == NULL || --key->nrefs > 0) return NULL; - wrlock lock(key->mutex); - if (--key->nrefs == 0) { - pgpDigParamsFree(key->pgpkey); - rpmPubkeyFree(key->primarykey); - delete key; - } + pgpDigParamsFree(key->pgpkey); + rpmPubkeyFree(key->primarykey); + delete key; + return NULL; } rpmPubkey rpmPubkeyLink(rpmPubkey key) { if (key) { - wrlock lock(key->mutex); key->nrefs++; } return key; diff --git a/rpmio/rpmstrpool.cc b/rpmio/rpmstrpool.cc index 8044f933e3..7fd2430f7c 100644 --- a/rpmio/rpmstrpool.cc +++ b/rpmio/rpmstrpool.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -43,7 +44,7 @@ struct rpmstrPool_s { poolHash hash; /* string -> sid hash table */ int frozen; /* are new id additions allowed? */ - int nrefs; /* refcount */ + std::atomic_int nrefs; /* refcount */ std::shared_mutex mutex; }; @@ -256,29 +257,25 @@ rpmstrPool rpmstrPoolCreate(void) rpmstrPool rpmstrPoolFree(rpmstrPool pool) { - if (pool) { - wrlock lock(pool->mutex); - if (pool->nrefs > 1) { - pool->nrefs--; - } else { - if (pool_debug) - poolHashPrintStats(pool); - poolHashFree(pool->hash); - free(pool->offs); - for (int i=1;i<=pool->chunks_size;i++) { - pool->chunks[i] = _free(pool->chunks[i]); - } - free(pool->chunks); - free(pool); - } + if (pool == NULL || --pool->nrefs > 0) + return NULL; + + if (pool_debug) + poolHashPrintStats(pool); + poolHashFree(pool->hash); + free(pool->offs); + for (int i=1; i<=pool->chunks_size; i++) { + pool->chunks[i] = _free(pool->chunks[i]); } + free(pool->chunks); + free(pool); + return NULL; } rpmstrPool rpmstrPoolLink(rpmstrPool pool) { if (pool) { - wrlock lock(pool->mutex); pool->nrefs++; } return pool;