async_wait.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (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_locl.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. ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, ERR_R_MALLOC_FAILURE);
  44. return 0;
  45. }
  46. fdlookup->key = key;
  47. fdlookup->fd = fd;
  48. fdlookup->custom_data = custom_data;
  49. fdlookup->cleanup = cleanup;
  50. fdlookup->add = 1;
  51. fdlookup->next = ctx->fds;
  52. ctx->fds = fdlookup;
  53. ctx->numadd++;
  54. return 1;
  55. }
  56. int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
  57. OSSL_ASYNC_FD *fd, void **custom_data)
  58. {
  59. struct fd_lookup_st *curr;
  60. curr = ctx->fds;
  61. while (curr != NULL) {
  62. if (curr->del) {
  63. /* This one has been marked deleted so do nothing */
  64. curr = curr->next;
  65. continue;
  66. }
  67. if (curr->key == key) {
  68. *fd = curr->fd;
  69. *custom_data = curr->custom_data;
  70. return 1;
  71. }
  72. curr = curr->next;
  73. }
  74. return 0;
  75. }
  76. int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
  77. size_t *numfds)
  78. {
  79. struct fd_lookup_st *curr;
  80. curr = ctx->fds;
  81. *numfds = 0;
  82. while (curr != NULL) {
  83. if (curr->del) {
  84. /* This one has been marked deleted so do nothing */
  85. curr = curr->next;
  86. continue;
  87. }
  88. if (fd != NULL) {
  89. *fd = curr->fd;
  90. fd++;
  91. }
  92. (*numfds)++;
  93. curr = curr->next;
  94. }
  95. return 1;
  96. }
  97. int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
  98. size_t *numaddfds, OSSL_ASYNC_FD *delfd,
  99. size_t *numdelfds)
  100. {
  101. struct fd_lookup_st *curr;
  102. *numaddfds = ctx->numadd;
  103. *numdelfds = ctx->numdel;
  104. if (addfd == NULL && delfd == NULL)
  105. return 1;
  106. curr = ctx->fds;
  107. while (curr != NULL) {
  108. /* We ignore fds that have been marked as both added and deleted */
  109. if (curr->del && !curr->add && (delfd != NULL)) {
  110. *delfd = curr->fd;
  111. delfd++;
  112. }
  113. if (curr->add && !curr->del && (addfd != NULL)) {
  114. *addfd = curr->fd;
  115. addfd++;
  116. }
  117. curr = curr->next;
  118. }
  119. return 1;
  120. }
  121. int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
  122. {
  123. struct fd_lookup_st *curr, *prev;
  124. curr = ctx->fds;
  125. prev = NULL;
  126. while (curr != NULL) {
  127. if (curr->del == 1) {
  128. /* This one has been marked deleted already so do nothing */
  129. prev = curr;
  130. curr = curr->next;
  131. continue;
  132. }
  133. if (curr->key == key) {
  134. /* If fd has just been added, remove it from the list */
  135. if (curr->add == 1) {
  136. if (ctx->fds == curr) {
  137. ctx->fds = curr->next;
  138. } else {
  139. prev->next = curr->next;
  140. }
  141. /* It is responsibility of the caller to cleanup before calling
  142. * ASYNC_WAIT_CTX_clear_fd
  143. */
  144. OPENSSL_free(curr);
  145. ctx->numadd--;
  146. return 1;
  147. }
  148. /*
  149. * Mark it as deleted. We don't call cleanup if explicitly asked
  150. * to clear an fd. We assume the caller is going to do that (if
  151. * appropriate).
  152. */
  153. curr->del = 1;
  154. ctx->numdel++;
  155. return 1;
  156. }
  157. prev = curr;
  158. curr = curr->next;
  159. }
  160. return 0;
  161. }
  162. void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
  163. {
  164. struct fd_lookup_st *curr, *prev = NULL;
  165. ctx->numadd = 0;
  166. ctx->numdel = 0;
  167. curr = ctx->fds;
  168. while (curr != NULL) {
  169. if (curr->del) {
  170. if (prev == NULL)
  171. ctx->fds = curr->next;
  172. else
  173. prev->next = curr->next;
  174. OPENSSL_free(curr);
  175. if (prev == NULL)
  176. curr = ctx->fds;
  177. else
  178. curr = prev->next;
  179. continue;
  180. }
  181. if (curr->add) {
  182. curr->add = 0;
  183. }
  184. prev = curr;
  185. curr = curr->next;
  186. }
  187. }