async_wait.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* This must be the first #include file */
  10. #include "async_local.h"
  11. #include <openssl/err.h>
  12. ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void)
  13. {
  14. return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX));
  15. }
  16. void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
  17. {
  18. struct fd_lookup_st *curr;
  19. struct fd_lookup_st *next;
  20. if (ctx == NULL)
  21. return;
  22. curr = ctx->fds;
  23. while (curr != NULL) {
  24. if (!curr->del) {
  25. /* Only try and cleanup if it hasn't been marked deleted */
  26. if (curr->cleanup != NULL)
  27. curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data);
  28. }
  29. /* Always free the fd_lookup_st */
  30. next = curr->next;
  31. OPENSSL_free(curr);
  32. curr = next;
  33. }
  34. OPENSSL_free(ctx);
  35. }
  36. int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
  37. OSSL_ASYNC_FD fd, void *custom_data,
  38. void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
  39. OSSL_ASYNC_FD, void *))
  40. {
  41. struct fd_lookup_st *fdlookup;
  42. if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL)
  43. return 0;
  44. fdlookup->key = key;
  45. fdlookup->fd = fd;
  46. fdlookup->custom_data = custom_data;
  47. fdlookup->cleanup = cleanup;
  48. fdlookup->add = 1;
  49. fdlookup->next = ctx->fds;
  50. ctx->fds = fdlookup;
  51. ctx->numadd++;
  52. return 1;
  53. }
  54. int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
  55. OSSL_ASYNC_FD *fd, void **custom_data)
  56. {
  57. struct fd_lookup_st *curr;
  58. curr = ctx->fds;
  59. while (curr != NULL) {
  60. if (curr->del) {
  61. /* This one has been marked deleted so do nothing */
  62. curr = curr->next;
  63. continue;
  64. }
  65. if (curr->key == key) {
  66. *fd = curr->fd;
  67. *custom_data = curr->custom_data;
  68. return 1;
  69. }
  70. curr = curr->next;
  71. }
  72. return 0;
  73. }
  74. int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
  75. size_t *numfds)
  76. {
  77. struct fd_lookup_st *curr;
  78. curr = ctx->fds;
  79. *numfds = 0;
  80. while (curr != NULL) {
  81. if (curr->del) {
  82. /* This one has been marked deleted so do nothing */
  83. curr = curr->next;
  84. continue;
  85. }
  86. if (fd != NULL) {
  87. *fd = curr->fd;
  88. fd++;
  89. }
  90. (*numfds)++;
  91. curr = curr->next;
  92. }
  93. return 1;
  94. }
  95. int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
  96. size_t *numaddfds, OSSL_ASYNC_FD *delfd,
  97. size_t *numdelfds)
  98. {
  99. struct fd_lookup_st *curr;
  100. *numaddfds = ctx->numadd;
  101. *numdelfds = ctx->numdel;
  102. if (addfd == NULL && delfd == NULL)
  103. return 1;
  104. curr = ctx->fds;
  105. while (curr != NULL) {
  106. /* We ignore fds that have been marked as both added and deleted */
  107. if (curr->del && !curr->add && (delfd != NULL)) {
  108. *delfd = curr->fd;
  109. delfd++;
  110. }
  111. if (curr->add && !curr->del && (addfd != NULL)) {
  112. *addfd = curr->fd;
  113. addfd++;
  114. }
  115. curr = curr->next;
  116. }
  117. return 1;
  118. }
  119. int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
  120. {
  121. struct fd_lookup_st *curr, *prev;
  122. curr = ctx->fds;
  123. prev = NULL;
  124. while (curr != NULL) {
  125. if (curr->del == 1) {
  126. /* This one has been marked deleted already so do nothing */
  127. prev = curr;
  128. curr = curr->next;
  129. continue;
  130. }
  131. if (curr->key == key) {
  132. /* If fd has just been added, remove it from the list */
  133. if (curr->add == 1) {
  134. if (ctx->fds == curr) {
  135. ctx->fds = curr->next;
  136. } else {
  137. prev->next = curr->next;
  138. }
  139. /* It is responsibility of the caller to cleanup before calling
  140. * ASYNC_WAIT_CTX_clear_fd
  141. */
  142. OPENSSL_free(curr);
  143. ctx->numadd--;
  144. return 1;
  145. }
  146. /*
  147. * Mark it as deleted. We don't call cleanup if explicitly asked
  148. * to clear an fd. We assume the caller is going to do that (if
  149. * appropriate).
  150. */
  151. curr->del = 1;
  152. ctx->numdel++;
  153. return 1;
  154. }
  155. prev = curr;
  156. curr = curr->next;
  157. }
  158. return 0;
  159. }
  160. int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx,
  161. ASYNC_callback_fn callback,
  162. void *callback_arg)
  163. {
  164. if (ctx == NULL)
  165. return 0;
  166. ctx->callback = callback;
  167. ctx->callback_arg = callback_arg;
  168. return 1;
  169. }
  170. int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx,
  171. ASYNC_callback_fn *callback,
  172. void **callback_arg)
  173. {
  174. if (ctx->callback == NULL)
  175. return 0;
  176. *callback = ctx->callback;
  177. *callback_arg = ctx->callback_arg;
  178. return 1;
  179. }
  180. int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status)
  181. {
  182. ctx->status = status;
  183. return 1;
  184. }
  185. int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx)
  186. {
  187. return ctx->status;
  188. }
  189. void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
  190. {
  191. struct fd_lookup_st *curr, *prev = NULL;
  192. ctx->numadd = 0;
  193. ctx->numdel = 0;
  194. curr = ctx->fds;
  195. while (curr != NULL) {
  196. if (curr->del) {
  197. if (prev == NULL)
  198. ctx->fds = curr->next;
  199. else
  200. prev->next = curr->next;
  201. OPENSSL_free(curr);
  202. if (prev == NULL)
  203. curr = ctx->fds;
  204. else
  205. curr = prev->next;
  206. continue;
  207. }
  208. if (curr->add) {
  209. curr->add = 0;
  210. }
  211. prev = curr;
  212. curr = curr->next;
  213. }
  214. }