GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/future.h
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 27 30 90.0%
Branches: 8 14 57.1%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_UTIL_FUTURE_H_
6 #define CVMFS_UTIL_FUTURE_H_
7
8 #include <pthread.h>
9
10 #include <cassert>
11
12 #include "util/mutex.h"
13 #include "util/single_copy.h"
14
15 #ifdef CVMFS_NAMESPACE_GUARD
16 namespace CVMFS_NAMESPACE_GUARD {
17 #endif
18
19 /**
20 * This is a simple implementation of a Future wrapper template.
21 * It is used as a proxy for results that are computed asynchronously and might
22 * not be available on the first access.
23 * Since this is a very simple implementation one needs to use the Future's
24 * Get() and Set() methods to obtain the containing data resp. to write it.
25 * Note: More than a single call to Set() is prohibited!
26 * If Get() is called before Set() the calling thread will block until
27 * the value has been set by a different thread.
28 *
29 * @param T the value type wrapped by this Future template
30 */
31 template <typename T>
32 class Future : SingleCopy {
33 public:
34 51 Future() : object_was_set_(false) {
35 51 int retval = pthread_mutex_init(&mutex_, NULL);
36
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(retval == 0);
37 51 retval = pthread_cond_init(&object_set_, NULL);
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(retval == 0);
39 51 }
40
41 51 ~Future() {
42 51 int retval = pthread_cond_destroy(&object_set_);
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(retval == 0);
44 51 retval = pthread_mutex_destroy(&mutex_);
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(retval == 0);
46 51 }
47
48 /**
49 * Save an asynchronously computed value into the Future. This potentially
50 * unblocks threads that already wait for the value.
51 * @param object the value object to be set
52 */
53 51 void Set(const T &object) {
54 51 MutexLockGuard guard(mutex_);
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(!object_was_set_);
56 51 object_ = object;
57 51 object_was_set_ = true;
58 51 pthread_cond_broadcast(&object_set_);
59 51 }
60
61 /**
62 * Retrieves the wrapped value object. If the value is not yet available it
63 * will automatically block until a different thread calls Set().
64 * @return the containing value object
65 */
66 51 T& Get() {
67 51 Wait();
68 51 return object_;
69 }
70
71 const T& Get() const {
72 Wait();
73 return object_;
74 }
75
76 private:
77 51 void Wait() const {
78 51 MutexLockGuard guard(mutex_);
79
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 51 times.
78 while (!object_was_set_) {
80
1/2
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
27 pthread_cond_wait(&object_set_, &mutex_);
81 }
82 51 }
83
84 T object_;
85 mutable pthread_mutex_t mutex_;
86 mutable pthread_cond_t object_set_;
87 bool object_was_set_;
88 };
89
90 #ifdef CVMFS_NAMESPACE_GUARD
91 } // namespace CVMFS_NAMESPACE_GUARD
92 #endif
93
94 #endif // CVMFS_UTIL_FUTURE_H_
95