From 4fc21fffa908f83148120d24e888148014805a82 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Thu, 10 Oct 2024 16:58:25 +0200 Subject: [PATCH] Turn FD_t->nrefs into atomic_int Throughout the code base reference counting is done in a thread-unsave way. Turn nrefs into atomic_int so they are thread-save themselves. As the nref can't change again after reaching zero this is thread-save even as we look at the result an instruction later. FD_t is special in that fdFree return the instance after free iff it still has not reached a ref count of 0. Unfortunately code in rpmShowProgress() relies on that. This does not make the data structures thread save on its own. But it gives a foundation on which data locking can be implemented. --- rpmio/rpmio.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) 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; }