| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/clientctx.cc |
| Date: | 2025-11-30 02:35:17 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 65 | 78 | 83.3% |
| Branches: | 22 | 40 | 55.0% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * This file is part of the CernVM File System. | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include "clientctx.h" | ||
| 6 | |||
| 7 | #include <cassert> | ||
| 8 | |||
| 9 | #include "interrupt.h" | ||
| 10 | #include "util/concurrency.h" | ||
| 11 | #include "util/smalloc.h" | ||
| 12 | |||
| 13 | using namespace std; // NOLINT | ||
| 14 | |||
| 15 | ClientCtx *ClientCtx::instance_ = NULL; | ||
| 16 | |||
| 17 | |||
| 18 | 1139 | void ClientCtx::CleanupInstance() { | |
| 19 |
2/2✓ Branch 0 taken 941 times.
✓ Branch 1 taken 198 times.
|
1139 | delete instance_; |
| 20 | 1139 | instance_ = NULL; | |
| 21 | 1139 | } | |
| 22 | |||
| 23 | |||
| 24 | 951 | ClientCtx::ClientCtx() { | |
| 25 | 951 | lock_tls_blocks_ = reinterpret_cast<pthread_mutex_t *>( | |
| 26 | 951 | smalloc(sizeof(pthread_mutex_t))); | |
| 27 | 951 | const int retval = pthread_mutex_init(lock_tls_blocks_, NULL); | |
| 28 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 951 times.
|
951 | assert(retval == 0); |
| 29 | 951 | } | |
| 30 | |||
| 31 | |||
| 32 | 941 | ClientCtx::~ClientCtx() { | |
| 33 | 941 | pthread_mutex_destroy(lock_tls_blocks_); | |
| 34 | 941 | free(lock_tls_blocks_); | |
| 35 | |||
| 36 |
2/2✓ Branch 1 taken 149 times.
✓ Branch 2 taken 941 times.
|
1090 | for (unsigned i = 0; i < tls_blocks_.size(); ++i) { |
| 37 |
1/2✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
|
149 | delete tls_blocks_[i]; |
| 38 | } | ||
| 39 | |||
| 40 | 941 | const int retval = pthread_key_delete(thread_local_storage_); | |
| 41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 941 times.
|
941 | assert(retval == 0); |
| 42 | 941 | } | |
| 43 | |||
| 44 | |||
| 45 | 2759 | ClientCtx *ClientCtx::GetInstance() { | |
| 46 |
2/2✓ Branch 0 taken 951 times.
✓ Branch 1 taken 1808 times.
|
2759 | if (instance_ == NULL) { |
| 47 | 951 | instance_ = new ClientCtx(); | |
| 48 | 951 | const int retval = pthread_key_create(&instance_->thread_local_storage_, | |
| 49 | TlsDestructor); | ||
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 951 times.
|
951 | assert(retval == 0); |
| 51 | } | ||
| 52 | |||
| 53 | 2759 | return instance_; | |
| 54 | } | ||
| 55 | |||
| 56 | |||
| 57 | 422 | void ClientCtx::Get(uid_t *uid, gid_t *gid, pid_t *pid, InterruptCue **ic) { | |
| 58 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 59 | 422 | pthread_getspecific(thread_local_storage_)); | |
| 60 |
4/4✓ Branch 0 taken 376 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 330 times.
|
422 | if ((tls == NULL) || !tls->is_set) { |
| 61 | 92 | *uid = -1; | |
| 62 | 92 | *gid = -1; | |
| 63 | 92 | *pid = -1; | |
| 64 | 92 | *ic = NULL; | |
| 65 | } else { | ||
| 66 | 330 | *uid = tls->uid; | |
| 67 | 330 | *gid = tls->gid; | |
| 68 | 330 | *pid = tls->pid; | |
| 69 | 330 | *ic = tls->interrupt_cue; | |
| 70 | } | ||
| 71 | 422 | } | |
| 72 | |||
| 73 | |||
| 74 | 1197 | bool ClientCtx::IsSet() { | |
| 75 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 76 | 1197 | pthread_getspecific(thread_local_storage_)); | |
| 77 |
2/2✓ Branch 0 taken 674 times.
✓ Branch 1 taken 523 times.
|
1197 | if (tls == NULL) |
| 78 | 674 | return false; | |
| 79 | |||
| 80 | 523 | return tls->is_set; | |
| 81 | } | ||
| 82 | |||
| 83 | |||
| 84 | 434 | void ClientCtx::Set(uid_t uid, gid_t gid, pid_t pid, InterruptCue *ic) { | |
| 85 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 86 | 434 | pthread_getspecific(thread_local_storage_)); | |
| 87 | |||
| 88 |
2/2✓ Branch 0 taken 149 times.
✓ Branch 1 taken 285 times.
|
434 | if (tls == NULL) { |
| 89 |
1/2✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
|
149 | tls = new ThreadLocalStorage(uid, gid, pid, ic); |
| 90 | 149 | const int retval = pthread_setspecific(thread_local_storage_, tls); | |
| 91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
|
149 | assert(retval == 0); |
| 92 | 149 | const MutexLockGuard lock_guard(lock_tls_blocks_); | |
| 93 |
1/2✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
|
149 | tls_blocks_.push_back(tls); |
| 94 | 149 | } else { | |
| 95 | 285 | tls->uid = uid; | |
| 96 | 285 | tls->gid = gid; | |
| 97 | 285 | tls->pid = pid; | |
| 98 | 285 | tls->interrupt_cue = ic; | |
| 99 | 285 | tls->is_set = true; | |
| 100 | } | ||
| 101 | 434 | } | |
| 102 | |||
| 103 | |||
| 104 | ✗ | void ClientCtx::TlsDestructor(void *data) { | |
| 105 | ✗ | ThreadLocalStorage *tls = static_cast<ClientCtx::ThreadLocalStorage *>(data); | |
| 106 | ✗ | delete tls; | |
| 107 | |||
| 108 | ✗ | assert(instance_); | |
| 109 | ✗ | const MutexLockGuard lock_guard(instance_->lock_tls_blocks_); | |
| 110 | ✗ | for (vector<ThreadLocalStorage *>::iterator | |
| 111 | ✗ | i = instance_->tls_blocks_.begin(), | |
| 112 | ✗ | iEnd = instance_->tls_blocks_.end(); | |
| 113 | ✗ | i != iEnd; | |
| 114 | ✗ | ++i) { | |
| 115 | ✗ | if ((*i) == tls) { | |
| 116 | ✗ | instance_->tls_blocks_.erase(i); | |
| 117 | ✗ | break; | |
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 123 | 158 | void ClientCtx::Unset() { | |
| 124 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 125 | 158 | pthread_getspecific(thread_local_storage_)); | |
| 126 |
1/2✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
|
158 | if (tls != NULL) { |
| 127 | 158 | tls->is_set = false; | |
| 128 | 158 | tls->uid = -1; | |
| 129 | 158 | tls->gid = -1; | |
| 130 | 158 | tls->pid = -1; | |
| 131 | 158 | tls->interrupt_cue = NULL; | |
| 132 | } | ||
| 133 | 158 | } | |
| 134 |