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