Directory: | cvmfs/ |
---|---|
File: | cvmfs/fd_refcount_mgr.cc |
Date: | 2025-06-08 02:35:55 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 80 | 80 | 100.0% |
Branches: | 45 | 76 | 59.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #include "fd_refcount_mgr.h" | ||
6 | |||
7 | #include <fcntl.h> | ||
8 | #include <unistd.h> | ||
9 | |||
10 | #include <cassert> | ||
11 | #include <string> | ||
12 | |||
13 | #include "util/mutex.h" | ||
14 | #include "util/smalloc.h" | ||
15 | |||
16 | |||
17 | 186 | int FdRefcountMgr::Open(const shash::Any id, const std::string &path) { | |
18 | 186 | int result = -1; | |
19 | 186 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
20 |
3/4✓ Branch 1 taken 186 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 179 times.
✓ Branch 4 taken 7 times.
|
186 | if (!map_fd_.Lookup(id, &result)) { |
21 |
1/2✓ Branch 2 taken 179 times.
✗ Branch 3 not taken.
|
179 | result = open(path.c_str(), O_RDONLY); |
22 |
2/2✓ Branch 0 taken 75 times.
✓ Branch 1 taken 104 times.
|
179 | if (result >= 0) { |
23 |
1/2✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
|
75 | map_fd_.Insert(id, result); |
24 | } | ||
25 | } | ||
26 |
2/2✓ Branch 0 taken 82 times.
✓ Branch 1 taken 104 times.
|
186 | if (result >= 0) { |
27 |
1/2✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
|
82 | FdRefcountInfo refc_info; |
28 |
3/4✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 75 times.
|
82 | if (map_refcount_.Lookup(result, &refc_info)) { |
29 | 7 | refc_info.refcount++; | |
30 | } else { | ||
31 | 75 | refc_info.refcount = 1; | |
32 | 75 | refc_info.id = id; | |
33 | } | ||
34 |
1/2✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
|
82 | map_refcount_.Insert(result, refc_info); |
35 | } | ||
36 | 186 | return result; | |
37 | 186 | } | |
38 | |||
39 | 78 | int FdRefcountMgr::Close(int fd) { | |
40 | 78 | int retval = -1; | |
41 | 78 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
42 |
1/2✓ Branch 1 taken 78 times.
✗ Branch 2 not taken.
|
78 | FdRefcountInfo refc_info; |
43 |
3/4✓ Branch 1 taken 78 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 77 times.
✓ Branch 4 taken 1 times.
|
78 | if (map_refcount_.Lookup(fd, &refc_info)) { |
44 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 71 times.
|
77 | if (refc_info.refcount > 1) { |
45 | 6 | refc_info.refcount -= 1; | |
46 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | map_refcount_.Insert(fd, refc_info); |
47 | 6 | retval = 0; | |
48 | } else { | ||
49 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | retval = close(fd); |
50 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | map_fd_.Erase(refc_info.id); |
51 |
1/2✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
|
71 | map_refcount_.Erase(fd); |
52 | } | ||
53 | } else { | ||
54 | // fd not present in our table - this should only happen | ||
55 | // when reloading from the normal posix cache manager! | ||
56 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | LogCvmfs(kLogCache, kLogDebug, |
57 | "WARNING: trying to close fd that " | ||
58 | " is not in refcount tables"); | ||
59 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | retval = close(fd); |
60 | } | ||
61 | 78 | return retval; | |
62 | 78 | } | |
63 | |||
64 | 4 | int FdRefcountMgr::Dup(int fd) { | |
65 | 4 | int retval = -1; | |
66 | 4 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
67 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | FdRefcountInfo refc_info; |
68 |
3/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
|
4 | if (map_refcount_.Lookup(fd, &refc_info)) { |
69 | 2 | refc_info.refcount += 1; | |
70 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | map_refcount_.Insert(fd, refc_info); |
71 | 2 | retval = fd; | |
72 | } else { | ||
73 | // fd not present in our table - this should | ||
74 | // not happen in the current usage of Dup | ||
75 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | LogCvmfs(kLogCache, kLogDebug, |
76 | "WARNING: trying to dup fd that " | ||
77 | " is not in refcount tables"); | ||
78 | 2 | retval = dup(fd); | |
79 | } | ||
80 | 4 | return retval; | |
81 | 4 | } | |
82 | |||
83 | 1 | FdRefcountMgr *FdRefcountMgr::Clone() { | |
84 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | FdRefcountMgr *clone = new FdRefcountMgr(map_refcount_, map_fd_); |
85 | 1 | return clone; | |
86 | } | ||
87 | |||
88 | 1 | SmallHashDynamic<shash::Any, int> *FdRefcountMgr::GetFdMapPtr() { | |
89 | 1 | return &map_fd_; | |
90 | } | ||
91 | |||
92 | SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo> * | ||
93 | 1 | FdRefcountMgr::GetRefcountMapPtr() { | |
94 | 1 | return &map_refcount_; | |
95 | } | ||
96 | |||
97 | 1 | void FdRefcountMgr::AssignFrom(FdRefcountMgr *other) { | |
98 | 1 | map_fd_ = *other->GetFdMapPtr(); | |
99 | 1 | map_refcount_ = *other->GetRefcountMapPtr(); | |
100 | 1 | } | |
101 | |||
102 | 170 | FdRefcountMgr::~FdRefcountMgr() { | |
103 | 170 | pthread_mutex_destroy(lock_cache_refcount_); | |
104 | 170 | free(lock_cache_refcount_); | |
105 | 170 | } | |
106 | |||
107 |
1/2✓ Branch 2 taken 171 times.
✗ Branch 3 not taken.
|
171 | FdRefcountMgr::FdRefcountMgr() { |
108 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | const shash::Any hash_null; |
109 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | map_fd_.Init(16, hash_null, hasher_any); |
110 |
1/2✓ Branch 1 taken 171 times.
✗ Branch 2 not taken.
|
171 | map_refcount_.Init(16, -1, hasher_int); |
111 | 171 | lock_cache_refcount_ = reinterpret_cast<pthread_mutex_t *>( | |
112 | 171 | smalloc(sizeof(pthread_mutex_t))); | |
113 | 171 | const int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 171 times.
|
171 | assert(retval == 0); |
115 | 171 | } | |
116 | |||
117 | 1 | FdRefcountMgr::FdRefcountMgr( | |
118 | const SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo> &map_refcount, | ||
119 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | const SmallHashDynamic<shash::Any, int> &map_fd) { |
120 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | const shash::Any hash_null; |
121 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | map_fd_.Init(16, hash_null, hasher_any); |
122 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | map_refcount_.Init(16, -1, hasher_int); |
123 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | map_refcount_ = map_refcount; |
124 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | map_fd_ = map_fd; |
125 | 1 | lock_cache_refcount_ = reinterpret_cast<pthread_mutex_t *>( | |
126 | 1 | smalloc(sizeof(pthread_mutex_t))); | |
127 | 1 | const int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
128 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | assert(retval == 0); |
129 | 1 | } | |
130 |