future.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #include "bt_common.h"
  19. #include "osi/allocator.h"
  20. #include "osi/future.h"
  21. #include "osi/osi.h"
  22. void future_free(future_t *future);
  23. future_t *future_new(void)
  24. {
  25. future_t *ret = osi_calloc(sizeof(future_t));
  26. if (!ret) {
  27. OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
  28. goto error;
  29. }
  30. if (osi_sem_new(&ret->semaphore, 1, 0) != 0) {
  31. OSI_TRACE_ERROR("%s unable to allocate memory for the semaphore.", __func__);
  32. goto error;
  33. }
  34. ret->ready_can_be_called = true;
  35. return ret;
  36. error:;
  37. future_free(ret);
  38. return NULL;
  39. }
  40. future_t *future_new_immediate(void *value)
  41. {
  42. future_t *ret = osi_calloc(sizeof(future_t));
  43. if (!ret) {
  44. OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__);
  45. goto error;
  46. }
  47. ret->result = value;
  48. ret->ready_can_be_called = false;
  49. return ret;
  50. error:;
  51. future_free(ret);
  52. return NULL;
  53. }
  54. void future_ready(future_t *future, void *value)
  55. {
  56. assert(future != NULL);
  57. assert(future->ready_can_be_called);
  58. future->ready_can_be_called = false;
  59. future->result = value;
  60. osi_sem_give(&future->semaphore);
  61. }
  62. void *future_await(future_t *future)
  63. {
  64. assert(future != NULL);
  65. // If the future is immediate, it will not have a semaphore
  66. if (future->semaphore) {
  67. osi_sem_take(&future->semaphore, OSI_SEM_MAX_TIMEOUT);
  68. }
  69. void *result = future->result;
  70. future_free(future);
  71. return result;
  72. }
  73. void future_free(future_t *future)
  74. {
  75. if (!future) {
  76. return;
  77. }
  78. if (future->semaphore) {
  79. osi_sem_free(&future->semaphore);
  80. }
  81. osi_free(future);
  82. }