Skip to content

Commit

Permalink
Turn FD_t->nrefs into atomic_int
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ffesti authored and dmnks committed Oct 15, 2024
1 parent c1453ce commit 4fc21ff
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions rpmio/rpmio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <dirent.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <atomic>

#include <rpm/rpmlog.h>
#include <rpm/rpmmacro.h>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 4fc21ff

Please sign in to comment.