GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/clientctx.cc Lines: 58 68 85.3 %
Date: 2019-02-03 02:48:13 Branches: 19 30 63.3 %

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 "smalloc.h"
10
#include "util_concurrency.h"
11
12
using namespace std;  // NOLINT
13
14
ClientCtx *ClientCtx::instance_ = NULL;
15
16
17
139
void ClientCtx::CleanupInstance() {
18
139
  delete instance_;
19
139
  instance_ = NULL;
20
139
}
21
22
23
111
ClientCtx::ClientCtx() {
24
  lock_tls_blocks_ = reinterpret_cast<pthread_mutex_t *>(
25
111
    smalloc(sizeof(pthread_mutex_t)));
26
111
  int retval = pthread_mutex_init(lock_tls_blocks_, NULL);
27
111
  assert(retval == 0);
28
111
}
29
30
31
108
ClientCtx::~ClientCtx() {
32
108
  pthread_mutex_destroy(lock_tls_blocks_);
33
108
  free(lock_tls_blocks_);
34
35
116
  for (unsigned i = 0; i < tls_blocks_.size(); ++i) {
36
8
    delete tls_blocks_[i];
37
  }
38
39
108
  int retval = pthread_key_delete(thread_local_storage_);
40
108
  assert(retval == 0);
41
}
42
43
44
299
ClientCtx *ClientCtx::GetInstance() {
45
299
  if (instance_ == NULL) {
46
111
    instance_ = new ClientCtx();
47
    int retval =
48
111
      pthread_key_create(&instance_->thread_local_storage_, TlsDestructor);
49
111
    assert(retval == 0);
50
  }
51
52
299
  return instance_;
53
}
54
55
56
13
void ClientCtx::Get(uid_t *uid, gid_t *gid, pid_t *pid) {
57
  ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>(
58
13
    pthread_getspecific(thread_local_storage_));
59

15
  if ((tls == NULL) || !tls->is_set) {
60
2
    *uid = -1;
61
2
    *gid = -1;
62
2
    *pid = -1;
63
  } else {
64
11
    *uid = tls->uid;
65
11
    *gid = tls->gid;
66
11
    *pid = tls->pid;
67
  }
68
13
}
69
70
71
144
bool ClientCtx::IsSet() {
72
  ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>(
73
144
    pthread_getspecific(thread_local_storage_));
74
144
  if (tls == NULL)
75
103
    return false;
76
77
41
  return tls->is_set;
78
}
79
80
81
40
void ClientCtx::Set(uid_t uid, gid_t gid, pid_t pid) {
82
  ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>(
83
40
    pthread_getspecific(thread_local_storage_));
84
85
40
  if (tls == NULL) {
86
8
    tls = new ThreadLocalStorage(uid, gid, pid);
87
8
    int retval = pthread_setspecific(thread_local_storage_, tls);
88
8
    assert(retval == 0);
89
8
    MutexLockGuard lock_guard(lock_tls_blocks_);
90
8
    tls_blocks_.push_back(tls);
91
  } else {
92
32
    tls->uid = uid;
93
32
    tls->gid = gid;
94
32
    tls->pid = pid;
95
32
    tls->is_set = true;
96
  }
97
40
}
98
99
100
void ClientCtx::TlsDestructor(void *data) {
101
  ThreadLocalStorage *tls = static_cast<ClientCtx::ThreadLocalStorage *>(data);
102
  delete tls;
103
104
  assert(instance_);
105
  MutexLockGuard lock_guard(instance_->lock_tls_blocks_);
106
  for (vector<ThreadLocalStorage *>::iterator i =
107
       instance_->tls_blocks_.begin(), iEnd = instance_->tls_blocks_.end();
108
       i != iEnd; ++i)
109
  {
110
    if ((*i) == tls) {
111
      instance_->tls_blocks_.erase(i);
112
      break;
113
    }
114
  }
115
}
116
117
118
34
void ClientCtx::Unset() {
119
  ThreadLocalStorage *tls = static_cast<ThreadLocalStorage *>(
120
34
    pthread_getspecific(thread_local_storage_));
121
34
  if (tls != NULL) {
122
34
    tls->is_set = false;
123
34
    tls->uid = -1;
124
34
    tls->gid = -1;
125
34
    tls->pid = -1;
126
  }
127
34
}