Line data Source code
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 <errno.h>
12 :
13 0 : static int process_error_code(int err) {
14 0 : switch (err) {
15 0 : case ENOMEM:
16 0 : return aws_raise_error(AWS_ERROR_OOM);
17 0 : case ETIMEDOUT:
18 0 : return aws_raise_error(AWS_ERROR_COND_VARIABLE_TIMED_OUT);
19 0 : default:
20 0 : return aws_raise_error(AWS_ERROR_COND_VARIABLE_ERROR_UNKNOWN);
21 0 : }
22 0 : }
23 :
24 0 : int aws_condition_variable_init(struct aws_condition_variable *condition_variable) {
25 0 : AWS_PRECONDITION(condition_variable);
26 0 :
27 0 : if (pthread_cond_init(&condition_variable->condition_handle, NULL)) {
28 0 : AWS_ZERO_STRUCT(*condition_variable);
29 0 : return aws_raise_error(AWS_ERROR_COND_VARIABLE_INIT_FAILED);
30 0 : }
31 0 :
32 0 : condition_variable->initialized = true;
33 0 : return AWS_OP_SUCCESS;
34 0 : }
35 :
36 0 : void aws_condition_variable_clean_up(struct aws_condition_variable *condition_variable) {
37 0 : AWS_PRECONDITION(condition_variable);
38 0 :
39 0 : if (condition_variable->initialized) {
40 0 : pthread_cond_destroy(&condition_variable->condition_handle);
41 0 : }
42 0 :
43 0 : AWS_ZERO_STRUCT(*condition_variable);
44 0 : }
45 :
46 0 : int aws_condition_variable_notify_one(struct aws_condition_variable *condition_variable) {
47 0 : AWS_PRECONDITION(condition_variable && condition_variable->initialized);
48 0 :
49 0 : int err_code = pthread_cond_signal(&condition_variable->condition_handle);
50 0 :
51 0 : if (err_code) {
52 0 : return process_error_code(err_code);
53 0 : }
54 0 :
55 0 : return AWS_OP_SUCCESS;
56 0 : }
57 :
58 0 : int aws_condition_variable_notify_all(struct aws_condition_variable *condition_variable) {
59 0 : AWS_PRECONDITION(condition_variable && condition_variable->initialized);
60 0 :
61 0 : int err_code = pthread_cond_broadcast(&condition_variable->condition_handle);
62 0 :
63 0 : if (err_code) {
64 0 : return process_error_code(err_code);
65 0 : }
66 0 :
67 0 : return AWS_OP_SUCCESS;
68 0 : }
69 :
70 0 : int aws_condition_variable_wait(struct aws_condition_variable *condition_variable, struct aws_mutex *mutex) {
71 0 : AWS_PRECONDITION(condition_variable && condition_variable->initialized);
72 0 : AWS_PRECONDITION(mutex && mutex->initialized);
73 0 :
74 0 : int err_code = pthread_cond_wait(&condition_variable->condition_handle, &mutex->mutex_handle);
75 0 :
76 0 : if (err_code) {
77 0 : return process_error_code(err_code);
78 0 : }
79 0 :
80 0 : return AWS_OP_SUCCESS;
81 0 : }
82 :
83 : int aws_condition_variable_wait_for(
84 : struct aws_condition_variable *condition_variable,
85 : struct aws_mutex *mutex,
86 0 : int64_t time_to_wait) {
87 0 :
88 0 : AWS_PRECONDITION(condition_variable && condition_variable->initialized);
89 0 : AWS_PRECONDITION(mutex && mutex->initialized);
90 0 :
91 0 : uint64_t current_sys_time = 0;
92 0 : if (aws_sys_clock_get_ticks(¤t_sys_time)) {
93 0 : return AWS_OP_ERR;
94 0 : }
95 0 :
96 0 : time_to_wait += current_sys_time;
97 0 :
98 0 : struct timespec ts;
99 0 : uint64_t remainder = 0;
100 0 : ts.tv_sec =
101 0 : (time_t)aws_timestamp_convert((uint64_t)time_to_wait, AWS_TIMESTAMP_NANOS, AWS_TIMESTAMP_SECS, &remainder);
102 0 : ts.tv_nsec = (long)remainder;
103 0 :
104 0 : int err_code = pthread_cond_timedwait(&condition_variable->condition_handle, &mutex->mutex_handle, &ts);
105 0 :
106 0 : if (err_code) {
107 0 : return process_error_code(err_code);
108 0 : }
109 0 :
110 0 : return AWS_OP_SUCCESS;
111 0 : }
|