Directory: | cvmfs/ |
---|---|
File: | cvmfs/fd_refcount_mgr.cc |
Date: | 2025-07-21 10:50:29 |
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 | 3454 | int FdRefcountMgr::Open(const shash::Any id, const std::string &path) { | |
18 | 3454 | int result = -1; | |
19 | 3454 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
20 |
3/4✓ Branch 1 taken 3454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3309 times.
✓ Branch 4 taken 145 times.
|
3454 | if (!map_fd_.Lookup(id, &result)) { |
21 |
1/2✓ Branch 2 taken 3309 times.
✗ Branch 3 not taken.
|
3309 | result = open(path.c_str(), O_RDONLY); |
22 |
2/2✓ Branch 0 taken 1359 times.
✓ Branch 1 taken 1950 times.
|
3309 | if (result >= 0) { |
23 |
1/2✓ Branch 1 taken 1359 times.
✗ Branch 2 not taken.
|
1359 | map_fd_.Insert(id, result); |
24 | } | ||
25 | } | ||
26 |
2/2✓ Branch 0 taken 1504 times.
✓ Branch 1 taken 1950 times.
|
3454 | if (result >= 0) { |
27 |
1/2✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
|
1504 | FdRefcountInfo refc_info; |
28 |
3/4✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 1359 times.
|
1504 | if (map_refcount_.Lookup(result, &refc_info)) { |
29 | 145 | refc_info.refcount++; | |
30 | } else { | ||
31 | 1359 | refc_info.refcount = 1; | |
32 | 1359 | refc_info.id = id; | |
33 | } | ||
34 |
1/2✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
|
1504 | map_refcount_.Insert(result, refc_info); |
35 | } | ||
36 | 3454 | return result; | |
37 | 3454 | } | |
38 | |||
39 | 1398 | int FdRefcountMgr::Close(int fd) { | |
40 | 1398 | int retval = -1; | |
41 | 1398 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
42 |
1/2✓ Branch 1 taken 1398 times.
✗ Branch 2 not taken.
|
1398 | FdRefcountInfo refc_info; |
43 |
3/4✓ Branch 1 taken 1398 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1375 times.
✓ Branch 4 taken 23 times.
|
1398 | if (map_refcount_.Lookup(fd, &refc_info)) { |
44 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 1255 times.
|
1375 | if (refc_info.refcount > 1) { |
45 | 120 | refc_info.refcount -= 1; | |
46 |
1/2✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
|
120 | map_refcount_.Insert(fd, refc_info); |
47 | 120 | retval = 0; | |
48 | } else { | ||
49 |
1/2✓ Branch 1 taken 1255 times.
✗ Branch 2 not taken.
|
1255 | retval = close(fd); |
50 |
1/2✓ Branch 1 taken 1255 times.
✗ Branch 2 not taken.
|
1255 | map_fd_.Erase(refc_info.id); |
51 |
1/2✓ Branch 1 taken 1255 times.
✗ Branch 2 not taken.
|
1255 | 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 23 times.
✗ Branch 2 not taken.
|
23 | LogCvmfs(kLogCache, kLogDebug, |
57 | "WARNING: trying to close fd that " | ||
58 | " is not in refcount tables"); | ||
59 |
1/2✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
|
23 | retval = close(fd); |
60 | } | ||
61 | 1398 | return retval; | |
62 | 1398 | } | |
63 | |||
64 | 106 | int FdRefcountMgr::Dup(int fd) { | |
65 | 106 | int retval = -1; | |
66 | 106 | const MutexLockGuard lock_guard(lock_cache_refcount_); | |
67 |
1/2✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
|
106 | FdRefcountInfo refc_info; |
68 |
3/4✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 53 times.
|
106 | if (map_refcount_.Lookup(fd, &refc_info)) { |
69 | 53 | refc_info.refcount += 1; | |
70 |
1/2✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
|
53 | map_refcount_.Insert(fd, refc_info); |
71 | 53 | 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 53 times.
✗ Branch 2 not taken.
|
53 | LogCvmfs(kLogCache, kLogDebug, |
76 | "WARNING: trying to dup fd that " | ||
77 | " is not in refcount tables"); | ||
78 | 53 | retval = dup(fd); | |
79 | } | ||
80 | 106 | return retval; | |
81 | 106 | } | |
82 | |||
83 | 20 | FdRefcountMgr *FdRefcountMgr::Clone() { | |
84 |
1/2✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
20 | FdRefcountMgr *clone = new FdRefcountMgr(map_refcount_, map_fd_); |
85 | 20 | return clone; | |
86 | } | ||
87 | |||
88 | 20 | SmallHashDynamic<shash::Any, int> *FdRefcountMgr::GetFdMapPtr() { | |
89 | 20 | return &map_fd_; | |
90 | } | ||
91 | |||
92 | SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo> * | ||
93 | 20 | FdRefcountMgr::GetRefcountMapPtr() { | |
94 | 20 | return &map_refcount_; | |
95 | } | ||
96 | |||
97 | 20 | void FdRefcountMgr::AssignFrom(FdRefcountMgr *other) { | |
98 | 20 | map_fd_ = *other->GetFdMapPtr(); | |
99 | 20 | map_refcount_ = *other->GetRefcountMapPtr(); | |
100 | 20 | } | |
101 | |||
102 | 4414 | FdRefcountMgr::~FdRefcountMgr() { | |
103 | 4414 | pthread_mutex_destroy(lock_cache_refcount_); | |
104 | 4414 | free(lock_cache_refcount_); | |
105 | 4414 | } | |
106 | |||
107 |
1/2✓ Branch 2 taken 4403 times.
✗ Branch 3 not taken.
|
4403 | FdRefcountMgr::FdRefcountMgr() { |
108 |
1/2✓ Branch 1 taken 4403 times.
✗ Branch 2 not taken.
|
4403 | const shash::Any hash_null; |
109 |
1/2✓ Branch 1 taken 4403 times.
✗ Branch 2 not taken.
|
4403 | map_fd_.Init(16, hash_null, hasher_any); |
110 |
1/2✓ Branch 1 taken 4403 times.
✗ Branch 2 not taken.
|
4403 | map_refcount_.Init(16, -1, hasher_int); |
111 | 4403 | lock_cache_refcount_ = reinterpret_cast<pthread_mutex_t *>( | |
112 | 4403 | smalloc(sizeof(pthread_mutex_t))); | |
113 | 4403 | const int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4403 times.
|
4403 | assert(retval == 0); |
115 | 4403 | } | |
116 | |||
117 | 20 | FdRefcountMgr::FdRefcountMgr( | |
118 | const SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo> &map_refcount, | ||
119 |
1/2✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
20 | const SmallHashDynamic<shash::Any, int> &map_fd) { |
120 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | const shash::Any hash_null; |
121 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | map_fd_.Init(16, hash_null, hasher_any); |
122 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | map_refcount_.Init(16, -1, hasher_int); |
123 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | map_refcount_ = map_refcount; |
124 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | map_fd_ = map_fd; |
125 | 20 | lock_cache_refcount_ = reinterpret_cast<pthread_mutex_t *>( | |
126 | 20 | smalloc(sizeof(pthread_mutex_t))); | |
127 | 20 | const int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
128 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | assert(retval == 0); |
129 | 20 | } | |
130 |