1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Google, Inc.
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 #include "bt_common.h"
20 #include "osi/allocator.h"
21 #include "osi/future.h"
22 #include "osi/osi.h"
23
24 void future_free(future_t *future);
25
future_new(void)26 future_t *future_new(void)
27 {
28 future_t *ret = osi_calloc(sizeof(future_t));
29 if (!ret) {
30 OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
31 goto error;
32 }
33
34 if (osi_sem_new(&ret->semaphore, 1, 0) != 0) {
35 OSI_TRACE_ERROR("%s unable to allocate memory for the semaphore.", __func__);
36 goto error;
37 }
38
39 ret->ready_can_be_called = true;
40 return ret;
41 error:;
42 future_free(ret);
43 return NULL;
44 }
45
future_new_immediate(void * value)46 future_t *future_new_immediate(void *value)
47 {
48 future_t *ret = osi_calloc(sizeof(future_t));
49 if (!ret) {
50 OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
51 goto error;
52 }
53
54 ret->result = value;
55 ret->ready_can_be_called = false;
56 return ret;
57 error:;
58 future_free(ret);
59 return NULL;
60 }
61
future_ready(future_t * future,void * value)62 void future_ready(future_t *future, void *value)
63 {
64 assert(future != NULL);
65 assert(future->ready_can_be_called);
66
67 future->ready_can_be_called = false;
68 future->result = value;
69 osi_sem_give(&future->semaphore);
70 }
71
future_await(future_t * future)72 void *future_await(future_t *future)
73 {
74 assert(future != NULL);
75
76 // If the future is immediate, it will not have a semaphore
77 if (future->semaphore) {
78 osi_sem_take(&future->semaphore, OSI_SEM_MAX_TIMEOUT);
79 }
80
81 void *result = future->result;
82 future_free(future);
83 return result;
84 }
85
future_free(future_t * future)86 void future_free(future_t *future)
87 {
88 if (!future) {
89 return;
90 }
91
92 if (future->semaphore) {
93 osi_sem_free(&future->semaphore);
94 }
95
96 osi_free(future);
97 }
98