GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/backoff.cc Lines: 36 38 94.7 %
Date: 2019-02-03 02:48:13 Branches: 6 10 60.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 *
4
 * Exponential backoff (sleep) with cutoff.
5
 */
6
7
#include "cvmfs_config.h"
8
#include "backoff.h"
9
10
#include <ctime>
11
12
#include "logging.h"
13
#include "smalloc.h"
14
#include "util/posix.h"
15
16
using namespace std;  // NOLINT
17
18
315
void BackoffThrottle::Init(const unsigned init_delay_ms,
19
                           const unsigned max_delay_ms,
20
                           const unsigned reset_after_ms)
21
{
22
315
  init_delay_ms_ = init_delay_ms;
23
315
  max_delay_ms_ = max_delay_ms;
24
315
  reset_after_ms_ = reset_after_ms;
25
315
  prng_.InitLocaltime();
26
27
  lock_ =
28
315
    reinterpret_cast<pthread_mutex_t *>(smalloc(sizeof(pthread_mutex_t)));
29
315
  int retval = pthread_mutex_init(lock_, NULL);
30
315
  assert(retval == 0);
31
32
315
  Reset();
33
315
}
34
35
36
315
BackoffThrottle::~BackoffThrottle() {
37
315
  pthread_mutex_destroy(lock_);
38
315
  free(lock_);
39
315
}
40
41
42
319
void BackoffThrottle::Reset() {
43
319
  pthread_mutex_lock(lock_);
44
319
  delay_range_ = 0;
45
319
  last_throttle_ = 0;
46
319
  pthread_mutex_unlock(lock_);
47
319
}
48
49
50
29
void BackoffThrottle::Throttle() {
51
29
  time_t now = time(NULL);
52
53
29
  pthread_mutex_lock(lock_);
54
29
  if (unsigned(now - last_throttle_) < reset_after_ms_/1000) {
55
5
    if (delay_range_ < max_delay_ms_) {
56
5
      if (delay_range_ == 0)
57
5
        delay_range_ = init_delay_ms_;
58
      else
59
        delay_range_ *= 2;
60
    }
61
5
    unsigned delay = prng_.Next(delay_range_) + 1;
62
5
    if (delay > max_delay_ms_)
63
      delay = max_delay_ms_;
64
65
5
    pthread_mutex_unlock(lock_);
66
5
    LogCvmfs(kLogCvmfs, kLogDebug, "backoff throttle %d ms", delay);
67
5
    SafeSleepMs(delay);
68
5
    pthread_mutex_lock(lock_);
69
  }
70
29
  last_throttle_ = now;
71
29
  pthread_mutex_unlock(lock_);
72
29
}