12e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson/******************************************************************************
22e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *
32e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  Copyright (C) 2014 Google, Inc.
42e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *
52e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  Licensed under the Apache License, Version 2.0 (the "License");
62e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  you may not use this file except in compliance with the License.
72e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  You may obtain a copy of the License at:
82e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *
92e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  http://www.apache.org/licenses/LICENSE-2.0
102e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *
112e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  Unless required by applicable law or agreed to in writing, software
122e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  distributed under the License is distributed on an "AS IS" BASIS,
132e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  See the License for the specific language governing permissions and
152e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *  limitations under the License.
162e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson *
172e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson ******************************************************************************/
182e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
19f8027005333c88a2f097cfd70d15c3d54c7764aeChris Manton#define LOG_TAG "bt_osi_future"
202e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
2149a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "osi/include/future.h"
2249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen
23f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He#include <base/logging.h>
242e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
250f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/allocator.h"
2644802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h"
2749a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "osi/include/osi.h"
280f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/semaphore.h"
292e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
302e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnsonstruct future_t {
312e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  bool ready_can_be_called;
32b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  semaphore_t* semaphore;  // NULL semaphore means immediate future
33b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  void* result;
342e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson};
352e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
36b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonstatic void future_free(future_t* future);
372e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
38b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonfuture_t* future_new(void) {
39b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  future_t* ret = static_cast<future_t*>(osi_calloc(sizeof(future_t)));
402e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
412e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  ret->semaphore = semaphore_new(0);
422e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  if (!ret->semaphore) {
43b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for the semaphore.",
44b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson              __func__);
452e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson    goto error;
462e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  }
472e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
482e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  ret->ready_can_be_called = true;
492e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  return ret;
502e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnsonerror:;
512e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  future_free(ret);
522e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  return NULL;
532e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson}
542e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
55b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonfuture_t* future_new_immediate(void* value) {
56b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  future_t* ret = static_cast<future_t*>(osi_calloc(sizeof(future_t)));
572e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
582e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  ret->result = value;
592e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  ret->ready_can_be_called = false;
60717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov  return ret;
612e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson}
622e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
63b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonvoid future_ready(future_t* future, void* value) {
64f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(future != NULL);
65f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(future->ready_can_be_called);
662e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
672e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  future->ready_can_be_called = false;
682e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  future->result = value;
692e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  semaphore_post(future->semaphore);
702e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson}
712e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
72b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonvoid* future_await(future_t* future) {
73f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(future != NULL);
742e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
752e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  // If the future is immediate, it will not have a semaphore
76b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  if (future->semaphore) semaphore_wait(future->semaphore);
772e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
78b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  void* result = future->result;
792e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  future_free(future);
802e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  return result;
812e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson}
822e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
83b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonstatic void future_free(future_t* future) {
84b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  if (!future) return;
852e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson
862e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  semaphore_free(future->semaphore);
872e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson  osi_free(future);
882e241dbe76facf02450c86d9fb4bf3d76d6dde21Zach Johnson}
89