Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / src / core / lib / gpr / sync_windows.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 /* Win32 code for gpr synchronization support. */
20
21 #include <grpc/support/port_platform.h>
22
23 #ifdef GPR_WINDOWS
24
25 #include <grpc/support/log.h>
26 #include <grpc/support/sync.h>
27 #include <grpc/support/time.h>
28
29 void gpr_mu_init(gpr_mu* mu) {
30   InitializeCriticalSection(&mu->cs);
31   mu->locked = 0;
32 }
33
34 void gpr_mu_destroy(gpr_mu* mu) { DeleteCriticalSection(&mu->cs); }
35
36 void gpr_mu_lock(gpr_mu* mu) {
37   EnterCriticalSection(&mu->cs);
38   GPR_ASSERT(!mu->locked);
39   mu->locked = 1;
40 }
41
42 void gpr_mu_unlock(gpr_mu* mu) {
43   mu->locked = 0;
44   LeaveCriticalSection(&mu->cs);
45 }
46
47 int gpr_mu_trylock(gpr_mu* mu) {
48   int result = TryEnterCriticalSection(&mu->cs);
49   if (result) {
50     if (mu->locked) {                /* This thread already holds the lock. */
51       LeaveCriticalSection(&mu->cs); /* Decrement lock count. */
52       result = 0;                    /* Indicate failure */
53     }
54     mu->locked = 1;
55   }
56   return result;
57 }
58
59 /*----------------------------------------*/
60
61 void gpr_cv_init(gpr_cv* cv) { InitializeConditionVariable(cv); }
62
63 void gpr_cv_destroy(gpr_cv* cv) {
64   /* Condition variables don't need destruction in Win32. */
65 }
66
67 int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
68   int timeout = 0;
69   DWORD timeout_max_ms;
70   mu->locked = 0;
71   if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
72       0) {
73     SleepConditionVariableCS(cv, &mu->cs, INFINITE);
74   } else {
75     abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
76     gpr_timespec now = gpr_now(abs_deadline.clock_type);
77     int64_t now_ms = (int64_t)now.tv_sec * 1000 + now.tv_nsec / 1000000;
78     int64_t deadline_ms =
79         (int64_t)abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000;
80     if (now_ms >= deadline_ms) {
81       timeout = 1;
82     } else {
83       if ((deadline_ms - now_ms) >= INFINITE) {
84         timeout_max_ms = INFINITE - 1;
85       } else {
86         timeout_max_ms = (DWORD)(deadline_ms - now_ms);
87       }
88       timeout = (SleepConditionVariableCS(cv, &mu->cs, timeout_max_ms) == 0 &&
89                  GetLastError() == ERROR_TIMEOUT);
90     }
91   }
92   mu->locked = 1;
93   return timeout;
94 }
95
96 void gpr_cv_signal(gpr_cv* cv) { WakeConditionVariable(cv); }
97
98 void gpr_cv_broadcast(gpr_cv* cv) { WakeAllConditionVariable(cv); }
99
100 /*----------------------------------------*/
101
102 static void* dummy;
103 struct run_once_func_arg {
104   void (*init_function)(void);
105 };
106 static BOOL CALLBACK run_once_func(gpr_once* once, void* v, void** pv) {
107   struct run_once_func_arg* arg = (struct run_once_func_arg*)v;
108   (*arg->init_function)();
109   return 1;
110 }
111
112 void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
113   struct run_once_func_arg arg;
114   arg.init_function = init_function;
115   InitOnceExecuteOnce(once, run_once_func, &arg, &dummy);
116 }
117
118 #endif /* GPR_WINDOWS */