Home | History | Annotate | Download | only in src
      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 "osi/include/future.h"
     22 
     23 #include <assert.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 = 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.", __func__);
     44     goto error;
     45   }
     46 
     47   ret->ready_can_be_called = true;
     48   return ret;
     49 error:;
     50   future_free(ret);
     51   return NULL;
     52 }
     53 
     54 future_t *future_new_immediate(void *value) {
     55   future_t *ret = osi_calloc(sizeof(future_t));
     56 
     57   ret->result = value;
     58   ret->ready_can_be_called = false;
     59   return ret;
     60 }
     61 
     62 void future_ready(future_t *future, void *value) {
     63   assert(future != NULL);
     64   assert(future->ready_can_be_called);
     65 
     66   future->ready_can_be_called = false;
     67   future->result = value;
     68   semaphore_post(future->semaphore);
     69 }
     70 
     71 void *future_await(future_t *future) {
     72   assert(future != NULL);
     73 
     74   // If the future is immediate, it will not have a semaphore
     75   if (future->semaphore)
     76     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)
     85     return;
     86 
     87   semaphore_free(future->semaphore);
     88   osi_free(future);
     89 }
     90