GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/fetch.h
Date: 2026-07-05 02:36:18
Exec Total Coverage
Lines: 17 26 65.4%
Branches: 3 14 21.4%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_FETCH_H_
6 #define CVMFS_FETCH_H_
7
8 #include <pthread.h>
9
10 #include <map>
11 #include <string>
12 #include <vector>
13
14 #include "cache.h"
15 #include "crypto/hash.h"
16 #include "duplex_testing.h"
17 #include "network/download.h"
18 #include "network/sink.h"
19
20 class BackoffThrottle;
21
22 namespace perf {
23 class Statistics;
24 }
25
26 namespace cvmfs {
27
28 /**
29 * TransacionSink uses an open transaction in a cache manager as a sink. It
30 * allows the download manager to write data without knowing about the cache
31 * manager.
32 */
33 class TransactionSink : public Sink {
34 public:
35 1436 TransactionSink(CacheManager *cache_mgr, void *open_txn)
36 1436 : Sink(false), cache_mgr_(cache_mgr), open_txn_(open_txn) { }
37 2872 virtual ~TransactionSink() { }
38
39 /**
40 * Appends data to the sink
41 *
42 * @returns on success: number of bytes written (can be less than requested)
43 * on failure: -errno.
44 */
45 2042 virtual int64_t Write(const void *buf, uint64_t sz) {
46 2042 return cache_mgr_->Write(buf, sz, open_txn_);
47 }
48
49 /**
50 * Truncate all written data and start over at position zero.
51 *
52 * @returns Success = 0
53 * Failure = -errno
54 */
55 257 virtual int Reset() { return cache_mgr_->Reset(open_txn_); }
56
57 /**
58 * Purges all resources leaving the sink in an invalid state.
59 * More aggressive version of Reset().
60 * For some sinks it might do the same as Reset().
61 *
62 * @returns Success = 0
63 * Failure = -errno
64 */
65 210 virtual int Purge() { return Reset(); }
66 /**
67 * @returns true if the object is correctly initialized.
68 */
69
2/4
✓ Branch 0 taken 1436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1436 times.
✗ Branch 3 not taken.
1436 virtual bool IsValid() { return cache_mgr_ != NULL && open_txn_ != NULL; }
70
71 1436 virtual int Flush() { return 0; }
72 virtual bool Reserve(size_t /*size*/) { return true; }
73 5396 virtual bool RequiresReserve() { return false; }
74
75 /**
76 * Return a string representation describing the type of sink and its status
77 */
78 virtual std::string Describe() {
79 std::string result = "Transaction sink that is ";
80 result += IsValid() ? "valid" : "invalid";
81 return result;
82 }
83
84 private:
85 CacheManager *cache_mgr_;
86 void *open_txn_;
87 };
88
89
90 /**
91 * The Fetcher uses a cache manager and a download manager in order to provide a
92 * (virtual) file descriptor to a requested object, which is valid in the
93 * context of the cache manager.
94 * If the object is not in the cache, it is downloaded and stored in the cache.
95 *
96 * Concurrent download requests for the same id are collapsed.
97 */
98 class Fetcher : SingleCopy {
99 FRIEND_TEST(T_Fetcher, GetTls);
100 FRIEND_TEST(T_Fetcher, SignalWaitingThreads);
101 friend void *TestGetTls(void *data);
102 friend void *TestFetchCollapse(void *data);
103 friend void *TestFetchCollapse2(void *data);
104 friend void TLSDestructor(void *data);
105
106 public:
107 Fetcher(CacheManager *cache_mgr,
108 download::DownloadManager *download_mgr,
109 BackoffThrottle *backoff_throttle,
110 perf::StatisticsTemplate statistics);
111 virtual ~Fetcher();
112
113 virtual int Fetch(const CacheManager::LabeledObject &object,
114 const std::string &alt_url = "");
115
116 void ReplaceCacheManager(CacheManager *new_cache_mgr) {
117 cache_mgr_ = new_cache_mgr;
118 }
119
120 /**
121 * Set the full-replica download manager used for partial replica failover.
122 * When the primary download fails with an HTTP error (404 from a partial
123 * Stratum-1), the download is retried using this manager whose host chain
124 * points to a full Stratum-1. Ownership is NOT transferred.
125 */
126 void SetFullReplicaDownloadManager(
127 download::DownloadManager *full_replica_mgr) {
128 full_replica_download_mgr_ = full_replica_mgr;
129 }
130
131 2302 CacheManager *cache_mgr() { return cache_mgr_; }
132 454 download::DownloadManager *download_mgr() { return download_mgr_; }
133
134 private:
135 /**
136 * Multiple threads might want to download the same object at the same time.
137 * If that happens, only the first thread performs the download. The other
138 * threads wait on a pipe for a notification from the first thread.
139 */
140 struct ThreadLocalStorage {
141
1/2
✓ Branch 2 taken 1139 times.
✗ Branch 3 not taken.
1139 ThreadLocalStorage() {
142 1139 pipe_wait[0] = -1;
143 1139 pipe_wait[1] = -1;
144 1139 fetcher = NULL;
145 1139 }
146
147 /**
148 * Used during cleanup to find tls_blocks_.
149 */
150 Fetcher *fetcher;
151 /**
152 * Wait on the reading end if another thread is already downloading the same
153 * object.
154 */
155 int pipe_wait[2];
156 /**
157 * Writer ends of all the pipes of threads that want to download the same
158 * object.
159 */
160 std::vector<int> other_pipes_waiting;
161 /**
162 * It is sufficient to construct the JobInfo object once per thread, not
163 * on every call to Fetch().
164 */
165 download::JobInfo download_job;
166 };
167
168 /**
169 * Maps currently downloaded chunks to the other_pipes_waiting member of the
170 * thread local storage of the downloading thread. This way, a thread can
171 * enqueue itself to such an other_pipes_waiting list and gets informed when
172 * the download is completed.
173 */
174 typedef std::map<shash::Any, std::vector<int> *> ThreadQueues;
175
176 ThreadLocalStorage *GetTls();
177 void CleanupTls(ThreadLocalStorage *tls);
178 void SignalWaitingThreads(const int fd, const shash::Any &id,
179 ThreadLocalStorage *tls);
180 int OpenSelect(const CacheManager::LabeledObject &object);
181
182 /**
183 * Key to the thread's ThreadLocalStorage memory
184 */
185 pthread_key_t thread_local_storage_;
186
187 ThreadQueues queues_download_;
188 pthread_mutex_t *lock_queues_download_;
189
190 /**
191 * All the threads register their thread local storage here, so that it can
192 * be cleaned up properly in the destructor of Fetcher.
193 */
194 std::vector<ThreadLocalStorage *> tls_blocks_;
195 pthread_mutex_t *lock_tls_blocks_;
196
197 CacheManager *cache_mgr_;
198 download::DownloadManager *download_mgr_;
199 /**
200 * Optional full-replica download manager for partial replica failover mode.
201 * Not owned by this Fetcher.
202 */
203 download::DownloadManager *full_replica_download_mgr_;
204 BackoffThrottle *backoff_throttle_;
205 perf::Counter *n_downloads;
206 perf::Counter *n_invocations;
207 };
208
209 } // namespace cvmfs
210
211 #endif // CVMFS_FETCH_H_
212
213