1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include <aws/common/condition_variable.h>
7
8 #include <aws/common/clock.h>
9 #include <aws/common/mutex.h>
10
11 #include <Windows.h>
12
13 #define AWSCV_TO_WINDOWS(pCV) (PCONDITION_VARIABLE) & (pCV)->condition_handle
14
aws_condition_variable_init(struct aws_condition_variable * condition_variable)15 int aws_condition_variable_init(struct aws_condition_variable *condition_variable) {
16 /* Ensure our condition variable and Windows' condition variables are the same size */
17 AWS_STATIC_ASSERT(sizeof(CONDITION_VARIABLE) == sizeof(condition_variable->condition_handle));
18
19 AWS_PRECONDITION(condition_variable);
20 InitializeConditionVariable(AWSCV_TO_WINDOWS(condition_variable));
21 condition_variable->initialized = true;
22 return AWS_OP_SUCCESS;
23 }
24
aws_condition_variable_clean_up(struct aws_condition_variable * condition_variable)25 void aws_condition_variable_clean_up(struct aws_condition_variable *condition_variable) {
26 AWS_PRECONDITION(condition_variable);
27 AWS_ZERO_STRUCT(*condition_variable);
28 }
29
aws_condition_variable_notify_one(struct aws_condition_variable * condition_variable)30 int aws_condition_variable_notify_one(struct aws_condition_variable *condition_variable) {
31 AWS_PRECONDITION(condition_variable && condition_variable->initialized);
32 WakeConditionVariable(AWSCV_TO_WINDOWS(condition_variable));
33 return AWS_OP_SUCCESS;
34 }
35
aws_condition_variable_notify_all(struct aws_condition_variable * condition_variable)36 int aws_condition_variable_notify_all(struct aws_condition_variable *condition_variable) {
37 AWS_PRECONDITION(condition_variable && condition_variable->initialized);
38 WakeAllConditionVariable(AWSCV_TO_WINDOWS(condition_variable));
39 return AWS_OP_SUCCESS;
40 }
41
aws_condition_variable_wait(struct aws_condition_variable * condition_variable,struct aws_mutex * mutex)42 int aws_condition_variable_wait(struct aws_condition_variable *condition_variable, struct aws_mutex *mutex) {
43 AWS_PRECONDITION(condition_variable && condition_variable->initialized);
44 AWS_PRECONDITION(mutex && mutex->initialized);
45
46 if (SleepConditionVariableSRW(AWSCV_TO_WINDOWS(condition_variable), AWSMUTEX_TO_WINDOWS(mutex), INFINITE, 0)) {
47 return AWS_OP_SUCCESS;
48 }
49
50 return aws_raise_error(AWS_ERROR_COND_VARIABLE_ERROR_UNKNOWN);
51 }
52
aws_condition_variable_wait_for(struct aws_condition_variable * condition_variable,struct aws_mutex * mutex,int64_t time_to_wait)53 int aws_condition_variable_wait_for(
54 struct aws_condition_variable *condition_variable,
55 struct aws_mutex *mutex,
56 int64_t time_to_wait) {
57
58 AWS_PRECONDITION(condition_variable && condition_variable->initialized);
59 AWS_PRECONDITION(mutex && mutex->initialized);
60
61 DWORD time_ms = (DWORD)aws_timestamp_convert(time_to_wait, AWS_TIMESTAMP_NANOS, AWS_TIMESTAMP_MILLIS, NULL);
62
63 if (SleepConditionVariableSRW(AWSCV_TO_WINDOWS(condition_variable), AWSMUTEX_TO_WINDOWS(mutex), time_ms, 0)) {
64 return AWS_OP_SUCCESS;
65 }
66
67 return aws_raise_error(AWS_ERROR_COND_VARIABLE_TIMED_OUT);
68 }
69