| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/clientctx.cc |
| Date: | 2025-11-09 02:35:23 |
| 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 | 1478 | void ClientCtx::CleanupInstance() { | |
| 19 |
2/2✓ Branch 0 taken 1261 times.
✓ Branch 1 taken 217 times.
|
1478 | delete instance_; |
| 20 | 1478 | instance_ = NULL; | |
| 21 | 1478 | } | |
| 22 | |||
| 23 | |||
| 24 | 1296 | ClientCtx::ClientCtx() { | |
| 25 | 1296 | lock_tls_blocks_ = reinterpret_cast<pthread_mutex_t *>( | |
| 26 | 1296 | smalloc(sizeof(pthread_mutex_t))); | |
| 27 | 1296 | const int retval = pthread_mutex_init(lock_tls_blocks_, NULL); | |
| 28 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1296 times.
|
1296 | assert(retval == 0); |
| 29 | 1296 | } | |
| 30 | |||
| 31 | |||
| 32 | 1261 | ClientCtx::~ClientCtx() { | |
| 33 | 1261 | pthread_mutex_destroy(lock_tls_blocks_); | |
| 34 | 1261 | free(lock_tls_blocks_); | |
| 35 | |||
| 36 |
2/2✓ Branch 1 taken 193 times.
✓ Branch 2 taken 1261 times.
|
1454 | for (unsigned i = 0; i < tls_blocks_.size(); ++i) { |
| 37 |
1/2✓ Branch 1 taken 193 times.
✗ Branch 2 not taken.
|
193 | delete tls_blocks_[i]; |
| 38 | } | ||
| 39 | |||
| 40 | 1261 | const int retval = pthread_key_delete(thread_local_storage_); | |
| 41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1261 times.
|
1261 | assert(retval == 0); |
| 42 | 1261 | } | |
| 43 | |||
| 44 | |||
| 45 | 4404 | ClientCtx *ClientCtx::GetInstance() { | |
| 46 |
2/2✓ Branch 0 taken 1296 times.
✓ Branch 1 taken 3108 times.
|
4404 | if (instance_ == NULL) { |
| 47 | 1296 | instance_ = new ClientCtx(); | |
| 48 | 1296 | const int retval = pthread_key_create(&instance_->thread_local_storage_, | |
| 49 | TlsDestructor); | ||
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1296 times.
|
1296 | assert(retval == 0); |
| 51 | } | ||
| 52 | |||
| 53 | 4404 | return instance_; | |
| 54 | } | ||
| 55 | |||
| 56 | |||
| 57 | 331 | void ClientCtx::Get(uid_t *uid, gid_t *gid, pid_t *pid, InterruptCue **ic) { | |
| 58 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 59 | 331 | pthread_getspecific(thread_local_storage_)); | |
| 60 |
4/4✓ Branch 0 taken 302 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 273 times.
|
331 | if ((tls == NULL) || !tls->is_set) { |
| 61 | 58 | *uid = -1; | |
| 62 | 58 | *gid = -1; | |
| 63 | 58 | *pid = -1; | |
| 64 | 58 | *ic = NULL; | |
| 65 | } else { | ||
| 66 | 273 | *uid = tls->uid; | |
| 67 | 273 | *gid = tls->gid; | |
| 68 | 273 | *pid = tls->pid; | |
| 69 | 273 | *ic = tls->interrupt_cue; | |
| 70 | } | ||
| 71 | 331 | } | |
| 72 | |||
| 73 | |||
| 74 | 2196 | bool ClientCtx::IsSet() { | |
| 75 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 76 | 2196 | pthread_getspecific(thread_local_storage_)); | |
| 77 |
2/2✓ Branch 0 taken 1346 times.
✓ Branch 1 taken 850 times.
|
2196 | if (tls == NULL) |
| 78 | 1346 | return false; | |
| 79 | |||
| 80 | 850 | return tls->is_set; | |
| 81 | } | ||
| 82 | |||
| 83 | |||
| 84 | 828 | void ClientCtx::Set(uid_t uid, gid_t gid, pid_t pid, InterruptCue *ic) { | |
| 85 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 86 | 828 | pthread_getspecific(thread_local_storage_)); | |
| 87 | |||
| 88 |
2/2✓ Branch 0 taken 193 times.
✓ Branch 1 taken 635 times.
|
828 | if (tls == NULL) { |
| 89 |
1/2✓ Branch 1 taken 193 times.
✗ Branch 2 not taken.
|
193 | tls = new ThreadLocalStorage(uid, gid, pid, ic); |
| 90 | 193 | const int retval = pthread_setspecific(thread_local_storage_, tls); | |
| 91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 193 times.
|
193 | assert(retval == 0); |
| 92 | 193 | const MutexLockGuard lock_guard(lock_tls_blocks_); | |
| 93 |
1/2✓ Branch 1 taken 193 times.
✗ Branch 2 not taken.
|
193 | tls_blocks_.push_back(tls); |
| 94 | 193 | } else { | |
| 95 | 635 | tls->uid = uid; | |
| 96 | 635 | tls->gid = gid; | |
| 97 | 635 | tls->pid = pid; | |
| 98 | 635 | tls->interrupt_cue = ic; | |
| 99 | 635 | tls->is_set = true; | |
| 100 | } | ||
| 101 | 828 | } | |
| 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 | 654 | void ClientCtx::Unset() { | |
| 124 | ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>( | ||
| 125 | 654 | pthread_getspecific(thread_local_storage_)); | |
| 126 |
1/2✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
|
654 | if (tls != NULL) { |
| 127 | 654 | tls->is_set = false; | |
| 128 | 654 | tls->uid = -1; | |
| 129 | 654 | tls->gid = -1; | |
| 130 | 654 | tls->pid = -1; | |
| 131 | 654 | tls->interrupt_cue = NULL; | |
| 132 | } | ||
| 133 | 654 | } | |
| 134 |