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 <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 }
    100