OSDN Git Service

DO NOT MERGE Use POSIX timer API for wake alarms instead of OSI callouts.
[android-x86/system-bt.git] / osi / src / future.c
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 #define LOG_TAG "bt_osi_future"
20
21 #include <assert.h>
22
23 #include "osi/include/allocator.h"
24 #include "osi/include/future.h"
25 #include "osi/include/osi.h"
26 #include "osi/include/log.h"
27 #include "osi/include/semaphore.h"
28
29 struct future_t {
30   bool ready_can_be_called;
31   semaphore_t *semaphore; // NULL semaphore means immediate future
32   void *result;
33 };
34
35 static void future_free(future_t *future);
36
37 future_t *future_new(void) {
38   future_t *ret = osi_calloc(sizeof(future_t));
39   if (!ret) {
40     LOG_ERROR("%s unable to allocate memory for return value.", __func__);
41     goto error;
42   }
43
44   ret->semaphore = semaphore_new(0);
45   if (!ret->semaphore) {
46     LOG_ERROR("%s unable to allocate memory for the semaphore.", __func__);
47     goto error;
48   }
49
50   ret->ready_can_be_called = true;
51   return ret;
52 error:;
53   future_free(ret);
54   return NULL;
55 }
56
57 future_t *future_new_immediate(void *value) {
58   future_t *ret = osi_calloc(sizeof(future_t));
59   if (!ret) {
60     LOG_ERROR("%s unable to allocate memory for return value.", __func__);
61     goto error;
62   }
63
64   ret->result = value;
65   ret->ready_can_be_called = false;
66  return ret;
67 error:;
68   future_free(ret);
69   return NULL;
70 }
71
72 void future_ready(future_t *future, void *value) {
73   assert(future != NULL);
74   assert(future->ready_can_be_called);
75
76   future->ready_can_be_called = false;
77   future->result = value;
78   semaphore_post(future->semaphore);
79 }
80
81 void *future_await(future_t *future) {
82   assert(future != NULL);
83
84   // If the future is immediate, it will not have a semaphore
85   if (future->semaphore)
86     semaphore_wait(future->semaphore);
87
88   void *result = future->result;
89   future_free(future);
90   return result;
91 }
92
93 static void future_free(future_t *future) {
94   if (!future)
95     return;
96
97   semaphore_free(future->semaphore);
98   osi_free(future);
99 }