File: timedlock.cpp

package info (click to toggle)
watchman 4.9.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,992 kB
  • sloc: cpp: 27,459; python: 6,538; java: 3,404; php: 3,257; ansic: 2,803; javascript: 1,116; makefile: 671; ruby: 364; sh: 124; xml: 102; lisp: 4
file content (43 lines) | stat: -rw-r--r-- 2,249 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Copyright 2016-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

#ifdef __APPLE__
// We get to emulate these functions because Darwin doesn't implement them

#define timed_helper(func_name, object_type, try_func)                   \
  int func_name(object_type* lock, const struct timespec* deadline_ts) { \
    int result;                                                          \
    struct timeval now, deadline;                                        \
    int usec = 1;                                                        \
    w_timespec_to_timeval(*deadline_ts, &deadline);                      \
    while (true) {                                                       \
      gettimeofday(&now, nullptr);                                       \
      if (w_timeval_compare(now, deadline) >= 0) {                       \
        return ETIMEDOUT;                                                \
      }                                                                  \
      result = try_func(lock);                                           \
      if (result != EBUSY) {                                             \
        return result;                                                   \
      }                                                                  \
      /* Exponential backoff on the sleep period */                      \
      usec = std::min(usec * 2, 1024);                                   \
      if (now.tv_sec == deadline.tv_sec) {                               \
        /* Cap the sleep if we are close to the deadline */              \
        usec = std::min(usec, deadline.tv_usec - now.tv_usec);           \
      }                                                                  \
      /* sleep override */ usleep(usec);                                 \
    }                                                                    \
  }

timed_helper(pthread_mutex_timedlock, pthread_mutex_t, pthread_mutex_trylock)
timed_helper(pthread_rwlock_timedwrlock, pthread_rwlock_t,
             pthread_rwlock_trywrlock)
timed_helper(pthread_rwlock_timedrdlock, pthread_rwlock_t,
             pthread_rwlock_tryrdlock)

#endif

/* vim:ts=2:sw=2:et:
 */