123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- /* This must be the first #include file */
- #include "async_local.h"
- #include <openssl/err.h>
- ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void)
- {
- return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX));
- }
- void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
- {
- struct fd_lookup_st *curr;
- struct fd_lookup_st *next;
- if (ctx == NULL)
- return;
- curr = ctx->fds;
- while (curr != NULL) {
- if (!curr->del) {
- /* Only try and cleanup if it hasn't been marked deleted */
- if (curr->cleanup != NULL)
- curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data);
- }
- /* Always free the fd_lookup_st */
- next = curr->next;
- OPENSSL_free(curr);
- curr = next;
- }
- OPENSSL_free(ctx);
- }
- int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
- OSSL_ASYNC_FD fd, void *custom_data,
- void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
- OSSL_ASYNC_FD, void *))
- {
- struct fd_lookup_st *fdlookup;
- if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) {
- ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- fdlookup->key = key;
- fdlookup->fd = fd;
- fdlookup->custom_data = custom_data;
- fdlookup->cleanup = cleanup;
- fdlookup->add = 1;
- fdlookup->next = ctx->fds;
- ctx->fds = fdlookup;
- ctx->numadd++;
- return 1;
- }
- int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
- OSSL_ASYNC_FD *fd, void **custom_data)
- {
- struct fd_lookup_st *curr;
- curr = ctx->fds;
- while (curr != NULL) {
- if (curr->del) {
- /* This one has been marked deleted so do nothing */
- curr = curr->next;
- continue;
- }
- if (curr->key == key) {
- *fd = curr->fd;
- *custom_data = curr->custom_data;
- return 1;
- }
- curr = curr->next;
- }
- return 0;
- }
- int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
- size_t *numfds)
- {
- struct fd_lookup_st *curr;
- curr = ctx->fds;
- *numfds = 0;
- while (curr != NULL) {
- if (curr->del) {
- /* This one has been marked deleted so do nothing */
- curr = curr->next;
- continue;
- }
- if (fd != NULL) {
- *fd = curr->fd;
- fd++;
- }
- (*numfds)++;
- curr = curr->next;
- }
- return 1;
- }
- int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
- size_t *numaddfds, OSSL_ASYNC_FD *delfd,
- size_t *numdelfds)
- {
- struct fd_lookup_st *curr;
- *numaddfds = ctx->numadd;
- *numdelfds = ctx->numdel;
- if (addfd == NULL && delfd == NULL)
- return 1;
- curr = ctx->fds;
- while (curr != NULL) {
- /* We ignore fds that have been marked as both added and deleted */
- if (curr->del && !curr->add && (delfd != NULL)) {
- *delfd = curr->fd;
- delfd++;
- }
- if (curr->add && !curr->del && (addfd != NULL)) {
- *addfd = curr->fd;
- addfd++;
- }
- curr = curr->next;
- }
- return 1;
- }
- int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
- {
- struct fd_lookup_st *curr, *prev;
- curr = ctx->fds;
- prev = NULL;
- while (curr != NULL) {
- if (curr->del == 1) {
- /* This one has been marked deleted already so do nothing */
- prev = curr;
- curr = curr->next;
- continue;
- }
- if (curr->key == key) {
- /* If fd has just been added, remove it from the list */
- if (curr->add == 1) {
- if (ctx->fds == curr) {
- ctx->fds = curr->next;
- } else {
- prev->next = curr->next;
- }
- /* It is responsibility of the caller to cleanup before calling
- * ASYNC_WAIT_CTX_clear_fd
- */
- OPENSSL_free(curr);
- ctx->numadd--;
- return 1;
- }
- /*
- * Mark it as deleted. We don't call cleanup if explicitly asked
- * to clear an fd. We assume the caller is going to do that (if
- * appropriate).
- */
- curr->del = 1;
- ctx->numdel++;
- return 1;
- }
- prev = curr;
- curr = curr->next;
- }
- return 0;
- }
- int ASYNC_WAIT_CTX_set_callback(ASYNC_WAIT_CTX *ctx,
- ASYNC_callback_fn callback,
- void *callback_arg)
- {
- if (ctx == NULL)
- return 0;
- ctx->callback = callback;
- ctx->callback_arg = callback_arg;
- return 1;
- }
- int ASYNC_WAIT_CTX_get_callback(ASYNC_WAIT_CTX *ctx,
- ASYNC_callback_fn *callback,
- void **callback_arg)
- {
- if (ctx->callback == NULL)
- return 0;
- *callback = ctx->callback;
- *callback_arg = ctx->callback_arg;
- return 1;
- }
- int ASYNC_WAIT_CTX_set_status(ASYNC_WAIT_CTX *ctx, int status)
- {
- ctx->status = status;
- return 1;
- }
- int ASYNC_WAIT_CTX_get_status(ASYNC_WAIT_CTX *ctx)
- {
- return ctx->status;
- }
- void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
- {
- struct fd_lookup_st *curr, *prev = NULL;
- ctx->numadd = 0;
- ctx->numdel = 0;
- curr = ctx->fds;
- while (curr != NULL) {
- if (curr->del) {
- if (prev == NULL)
- ctx->fds = curr->next;
- else
- prev->next = curr->next;
- OPENSSL_free(curr);
- if (prev == NULL)
- curr = ctx->fds;
- else
- curr = prev->next;
- continue;
- }
- if (curr->add) {
- curr->add = 0;
- }
- prev = curr;
- curr = curr->next;
- }
- }
|