Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 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 "osi/include/future.h"
     22 
     23 #include <base/logging.h>
     24 
     25 #include "osi/include/allocator.h"
     26 #include "osi/include/log.h"
     27 #include "osi/include/osi.h"
     28 #include "osi/include/semaphore.h"
     29 
     30 struct future_t {
     31   bool ready_can_be_called;
     32   semaphore_t* semaphore;  // NULL semaphore means immediate future
     33   void* result;
     34 };
     35 
     36 static void future_free(future_t* future);
     37 
     38 future_t* future_new(void) {
     39   future_t* ret = static_cast<future_t*>(osi_calloc(sizeof(future_t)));
     40 
     41   ret->semaphore = semaphore_new(0);
     42   if (!ret->semaphore) {
     43     LOG_ERROR(LOG_TAG, "%s unable to allocate memory for the semaphore.",
     44               __func__);
     45     goto error;
     46   }
     47 
     48   ret->ready_can_be_called = true;
     49   return ret;
     50 error:;
     51   future_free(ret);
     52   return NULL;
     53 }
     54 
     55 future_t* future_new_immediate(void* value) {
     56   future_t* ret = static_cast<future_t*>(osi_calloc(sizeof(future_t)));
     57 
     58   ret->result = value;
     59   ret->ready_can_be_called = false;
     60   return ret;
     61 }
     62 
     63 void future_ready(future_t* future, void* value) {
     64   CHECK(future != NULL);
     65   CHECK(future->ready_can_be_called);
     66 
     67   future->ready_can_be_called = false;
     68   future->result = value;
     69   semaphore_post(future->semaphore);
     70 }
     71 
     72 void* future_await(future_t* future) {
     73   CHECK(future != NULL);
     74 
     75   // If the future is immediate, it will not have a semaphore
     76   if (future->semaphore) semaphore_wait(future->semaphore);
     77 
     78   void* result = future->result;
     79   future_free(future);
     80   return result;
     81 }
     82 
     83 static void future_free(future_t* future) {
     84   if (!future) return;
     85 
     86   semaphore_free(future->semaphore);
     87   osi_free(future);
     88 }
     89