diff options
author | deshevoy <deshevoy@yandex-team.ru> | 2022-02-10 16:46:57 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:57 +0300 |
commit | 28148f76dbfcc644d96427d41c92f36cbf2fdc6e (patch) | |
tree | b83306b6e37edeea782e9eed673d89286c4fef35 /contrib/libs/openssl/crypto/async | |
parent | e988f30484abe5fdeedcc7a5d3c226c01a21800c (diff) | |
download | ydb-28148f76dbfcc644d96427d41c92f36cbf2fdc6e.tar.gz |
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/async')
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_null.c | 44 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_null.h | 60 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_posix.c | 114 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_posix.h | 110 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_win.c | 108 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/arch/async_win.h | 72 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/async.c | 898 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/async_err.c | 102 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/async/async_wait.c | 424 |
9 files changed, 966 insertions, 966 deletions
diff --git a/contrib/libs/openssl/crypto/async/arch/async_null.c b/contrib/libs/openssl/crypto/async/arch/async_null.c index 8d470ba2b9..26801f8731 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_null.c +++ b/contrib/libs/openssl/crypto/async/arch/async_null.c @@ -1,23 +1,23 @@ -/* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 */ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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" - -#ifdef ASYNC_NULL -int ASYNC_is_capable(void) -{ - return 0; -} - -void async_local_cleanup(void) -{ -} -#endif - + +#ifdef ASYNC_NULL +int ASYNC_is_capable(void) +{ + return 0; +} + +void async_local_cleanup(void) +{ +} +#endif + diff --git a/contrib/libs/openssl/crypto/async/arch/async_null.h b/contrib/libs/openssl/crypto/async/arch/async_null.h index 950cd4bc5b..aef40b5d9e 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_null.h +++ b/contrib/libs/openssl/crypto/async/arch/async_null.h @@ -1,30 +1,30 @@ -/* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - -#include <openssl/async.h> - -/* - * If we haven't managed to detect any other async architecture then we default - * to NULL. - */ -#ifndef ASYNC_ARCH -# define ASYNC_NULL -# define ASYNC_ARCH - -typedef struct async_fibre_st { - int dummy; -} async_fibre; - - -# define async_fibre_swapcontext(o,n,r) 0 -# define async_fibre_makecontext(c) 0 -# define async_fibre_free(f) -# define async_fibre_init_dispatcher(f) - -#endif +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + +#include <openssl/async.h> + +/* + * If we haven't managed to detect any other async architecture then we default + * to NULL. + */ +#ifndef ASYNC_ARCH +# define ASYNC_NULL +# define ASYNC_ARCH + +typedef struct async_fibre_st { + int dummy; +} async_fibre; + + +# define async_fibre_swapcontext(o,n,r) 0 +# define async_fibre_makecontext(c) 0 +# define async_fibre_free(f) +# define async_fibre_init_dispatcher(f) + +#endif diff --git a/contrib/libs/openssl/crypto/async/arch/async_posix.c b/contrib/libs/openssl/crypto/async/arch/async_posix.c index 62759c0535..95678d4fa6 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_posix.c +++ b/contrib/libs/openssl/crypto/async/arch/async_posix.c @@ -1,58 +1,58 @@ -/* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 */ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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" - -#ifdef ASYNC_POSIX - -# include <stddef.h> -# include <unistd.h> - -#define STACKSIZE 32768 - -int ASYNC_is_capable(void) -{ - ucontext_t ctx; - - /* - * Some platforms provide getcontext() but it does not work (notably - * MacOSX PPC64). Check for a working getcontext(); - */ - return getcontext(&ctx) == 0; -} - -void async_local_cleanup(void) -{ -} - -int async_fibre_makecontext(async_fibre *fibre) -{ - fibre->env_init = 0; - if (getcontext(&fibre->fibre) == 0) { - fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE); - if (fibre->fibre.uc_stack.ss_sp != NULL) { - fibre->fibre.uc_stack.ss_size = STACKSIZE; - fibre->fibre.uc_link = NULL; - makecontext(&fibre->fibre, async_start_func, 0); - return 1; - } - } else { - fibre->fibre.uc_stack.ss_sp = NULL; - } - return 0; -} - -void async_fibre_free(async_fibre *fibre) -{ - OPENSSL_free(fibre->fibre.uc_stack.ss_sp); - fibre->fibre.uc_stack.ss_sp = NULL; -} - -#endif + +#ifdef ASYNC_POSIX + +# include <stddef.h> +# include <unistd.h> + +#define STACKSIZE 32768 + +int ASYNC_is_capable(void) +{ + ucontext_t ctx; + + /* + * Some platforms provide getcontext() but it does not work (notably + * MacOSX PPC64). Check for a working getcontext(); + */ + return getcontext(&ctx) == 0; +} + +void async_local_cleanup(void) +{ +} + +int async_fibre_makecontext(async_fibre *fibre) +{ + fibre->env_init = 0; + if (getcontext(&fibre->fibre) == 0) { + fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE); + if (fibre->fibre.uc_stack.ss_sp != NULL) { + fibre->fibre.uc_stack.ss_size = STACKSIZE; + fibre->fibre.uc_link = NULL; + makecontext(&fibre->fibre, async_start_func, 0); + return 1; + } + } else { + fibre->fibre.uc_stack.ss_sp = NULL; + } + return 0; +} + +void async_fibre_free(async_fibre *fibre) +{ + OPENSSL_free(fibre->fibre.uc_stack.ss_sp); + fibre->fibre.uc_stack.ss_sp = NULL; +} + +#endif diff --git a/contrib/libs/openssl/crypto/async/arch/async_posix.h b/contrib/libs/openssl/crypto/async/arch/async_posix.h index a701235188..873c0316dd 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_posix.h +++ b/contrib/libs/openssl/crypto/async/arch/async_posix.h @@ -1,58 +1,58 @@ -/* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + #ifndef OSSL_CRYPTO_ASYNC_POSIX_H #define OSSL_CRYPTO_ASYNC_POSIX_H -#include <openssl/e_os2.h> - -#if defined(OPENSSL_SYS_UNIX) \ - && defined(OPENSSL_THREADS) && !defined(OPENSSL_NO_ASYNC) \ - && !defined(__ANDROID__) && !defined(__OpenBSD__) - -# include <unistd.h> - -# if _POSIX_VERSION >= 200112L \ - && (_POSIX_VERSION < 200809L || defined(__GLIBC__)) - -# include <pthread.h> - -# define ASYNC_POSIX -# define ASYNC_ARCH - -# include <ucontext.h> -# include <setjmp.h> - -typedef struct async_fibre_st { - ucontext_t fibre; - jmp_buf env; - int env_init; -} async_fibre; - -static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) -{ - o->env_init = 1; - - if (!r || !_setjmp(o->env)) { - if (n->env_init) - _longjmp(n->env, 1); - else - setcontext(&n->fibre); - } - - return 1; -} - -# define async_fibre_init_dispatcher(d) - -int async_fibre_makecontext(async_fibre *fibre); -void async_fibre_free(async_fibre *fibre); - -# endif -#endif +#include <openssl/e_os2.h> + +#if defined(OPENSSL_SYS_UNIX) \ + && defined(OPENSSL_THREADS) && !defined(OPENSSL_NO_ASYNC) \ + && !defined(__ANDROID__) && !defined(__OpenBSD__) + +# include <unistd.h> + +# if _POSIX_VERSION >= 200112L \ + && (_POSIX_VERSION < 200809L || defined(__GLIBC__)) + +# include <pthread.h> + +# define ASYNC_POSIX +# define ASYNC_ARCH + +# include <ucontext.h> +# include <setjmp.h> + +typedef struct async_fibre_st { + ucontext_t fibre; + jmp_buf env; + int env_init; +} async_fibre; + +static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) +{ + o->env_init = 1; + + if (!r || !_setjmp(o->env)) { + if (n->env_init) + _longjmp(n->env, 1); + else + setcontext(&n->fibre); + } + + return 1; +} + +# define async_fibre_init_dispatcher(d) + +int async_fibre_makecontext(async_fibre *fibre); +void async_fibre_free(async_fibre *fibre); + +# endif +#endif #endif /* OSSL_CRYPTO_ASYNC_POSIX_H */ diff --git a/contrib/libs/openssl/crypto/async/arch/async_win.c b/contrib/libs/openssl/crypto/async/arch/async_win.c index 639571b1dc..1f360d895b 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_win.c +++ b/contrib/libs/openssl/crypto/async/arch/async_win.c @@ -1,55 +1,55 @@ -/* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 */ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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" - -#ifdef ASYNC_WIN - -# include <windows.h> -# include "internal/cryptlib.h" - -int ASYNC_is_capable(void) -{ - return 1; -} - -void async_local_cleanup(void) -{ - async_ctx *ctx = async_get_ctx(); - if (ctx != NULL) { - async_fibre *fibre = &ctx->dispatcher; - if (fibre != NULL && fibre->fibre != NULL && fibre->converted) { - ConvertFiberToThread(); - fibre->fibre = NULL; - } - } -} - -int async_fibre_init_dispatcher(async_fibre *fibre) -{ - fibre->fibre = ConvertThreadToFiber(NULL); - if (fibre->fibre == NULL) { - fibre->converted = 0; - fibre->fibre = GetCurrentFiber(); - if (fibre->fibre == NULL) - return 0; - } else { - fibre->converted = 1; - } - - return 1; -} - -VOID CALLBACK async_start_func_win(PVOID unused) -{ - async_start_func(); -} - -#endif + +#ifdef ASYNC_WIN + +# include <windows.h> +# include "internal/cryptlib.h" + +int ASYNC_is_capable(void) +{ + return 1; +} + +void async_local_cleanup(void) +{ + async_ctx *ctx = async_get_ctx(); + if (ctx != NULL) { + async_fibre *fibre = &ctx->dispatcher; + if (fibre != NULL && fibre->fibre != NULL && fibre->converted) { + ConvertFiberToThread(); + fibre->fibre = NULL; + } + } +} + +int async_fibre_init_dispatcher(async_fibre *fibre) +{ + fibre->fibre = ConvertThreadToFiber(NULL); + if (fibre->fibre == NULL) { + fibre->converted = 0; + fibre->fibre = GetCurrentFiber(); + if (fibre->fibre == NULL) + return 0; + } else { + fibre->converted = 1; + } + + return 1; +} + +VOID CALLBACK async_start_func_win(PVOID unused) +{ + async_start_func(); +} + +#endif diff --git a/contrib/libs/openssl/crypto/async/arch/async_win.h b/contrib/libs/openssl/crypto/async/arch/async_win.h index fd89c58e15..61cfdd72de 100644 --- a/contrib/libs/openssl/crypto/async/arch/async_win.h +++ b/contrib/libs/openssl/crypto/async/arch/async_win.h @@ -1,36 +1,36 @@ -/* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 is the same detection used in cryptlib to set up the thread local - * storage that we depend on, so just copy that - */ -#if defined(_WIN32) && !defined(OPENSSL_NO_ASYNC) -#include <openssl/async.h> -# define ASYNC_WIN -# define ASYNC_ARCH - -# include <windows.h> -# include "internal/cryptlib.h" - -typedef struct async_fibre_st { - LPVOID fibre; - int converted; -} async_fibre; - -# define async_fibre_swapcontext(o,n,r) \ - (SwitchToFiber((n)->fibre), 1) -# define async_fibre_makecontext(c) \ - ((c)->fibre = CreateFiber(0, async_start_func_win, 0)) -# define async_fibre_free(f) (DeleteFiber((f)->fibre)) - -int async_fibre_init_dispatcher(async_fibre *fibre); -VOID CALLBACK async_start_func_win(PVOID unused); - -#endif +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 is the same detection used in cryptlib to set up the thread local + * storage that we depend on, so just copy that + */ +#if defined(_WIN32) && !defined(OPENSSL_NO_ASYNC) +#include <openssl/async.h> +# define ASYNC_WIN +# define ASYNC_ARCH + +# include <windows.h> +# include "internal/cryptlib.h" + +typedef struct async_fibre_st { + LPVOID fibre; + int converted; +} async_fibre; + +# define async_fibre_swapcontext(o,n,r) \ + (SwitchToFiber((n)->fibre), 1) +# define async_fibre_makecontext(c) \ + ((c)->fibre = CreateFiber(0, async_start_func_win, 0)) +# define async_fibre_free(f) (DeleteFiber((f)->fibre)) + +int async_fibre_init_dispatcher(async_fibre *fibre); +VOID CALLBACK async_start_func_win(PVOID unused); + +#endif diff --git a/contrib/libs/openssl/crypto/async/async.c b/contrib/libs/openssl/crypto/async/async.c index 125b78c55a..326015c605 100644 --- a/contrib/libs/openssl/crypto/async/async.c +++ b/contrib/libs/openssl/crypto/async/async.c @@ -1,451 +1,451 @@ -/* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - -/* - * Without this we start getting longjmp crashes because it thinks we're jumping - * up the stack when in fact we are jumping to an entirely different stack. The - * cost of this is not having certain buffer overrun/underrun checks etc for - * this source file :-( - */ -#undef _FORTIFY_SOURCE - -/* This must be the first #include file */ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + +/* + * Without this we start getting longjmp crashes because it thinks we're jumping + * up the stack when in fact we are jumping to an entirely different stack. The + * cost of this is not having certain buffer overrun/underrun checks etc for + * this source file :-( + */ +#undef _FORTIFY_SOURCE + +/* This must be the first #include file */ #include "async_local.h" - -#include <openssl/err.h> + +#include <openssl/err.h> #include "crypto/cryptlib.h" -#include <string.h> - -#define ASYNC_JOB_RUNNING 0 -#define ASYNC_JOB_PAUSING 1 -#define ASYNC_JOB_PAUSED 2 -#define ASYNC_JOB_STOPPING 3 - -static CRYPTO_THREAD_LOCAL ctxkey; -static CRYPTO_THREAD_LOCAL poolkey; - -static async_ctx *async_ctx_new(void) -{ - async_ctx *nctx; - - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) - return NULL; - - nctx = OPENSSL_malloc(sizeof(*nctx)); - if (nctx == NULL) { - ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE); - goto err; - } - - async_fibre_init_dispatcher(&nctx->dispatcher); - nctx->currjob = NULL; - nctx->blocked = 0; - if (!CRYPTO_THREAD_set_local(&ctxkey, nctx)) - goto err; - - return nctx; -err: - OPENSSL_free(nctx); - - return NULL; -} - -async_ctx *async_get_ctx(void) -{ - return (async_ctx *)CRYPTO_THREAD_get_local(&ctxkey); -} - -static int async_ctx_free(void) -{ - async_ctx *ctx; - - ctx = async_get_ctx(); - - if (!CRYPTO_THREAD_set_local(&ctxkey, NULL)) - return 0; - - OPENSSL_free(ctx); - - return 1; -} - -static ASYNC_JOB *async_job_new(void) -{ - ASYNC_JOB *job = NULL; - - job = OPENSSL_zalloc(sizeof(*job)); - if (job == NULL) { - ASYNCerr(ASYNC_F_ASYNC_JOB_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - job->status = ASYNC_JOB_RUNNING; - - return job; -} - -static void async_job_free(ASYNC_JOB *job) -{ - if (job != NULL) { - OPENSSL_free(job->funcargs); - async_fibre_free(&job->fibrectx); - OPENSSL_free(job); - } -} - -static ASYNC_JOB *async_get_pool_job(void) { - ASYNC_JOB *job; - async_pool *pool; - - pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); - if (pool == NULL) { - /* - * Pool has not been initialised, so init with the defaults, i.e. - * no max size and no pre-created jobs - */ - if (ASYNC_init_thread(0, 0) == 0) - return NULL; - pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); - } - - job = sk_ASYNC_JOB_pop(pool->jobs); - if (job == NULL) { - /* Pool is empty */ - if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size)) - return NULL; - - job = async_job_new(); - if (job != NULL) { - if (! async_fibre_makecontext(&job->fibrectx)) { - async_job_free(job); - return NULL; - } - pool->curr_size++; - } - } - return job; -} - -static void async_release_job(ASYNC_JOB *job) { - async_pool *pool; - - pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); - OPENSSL_free(job->funcargs); - job->funcargs = NULL; - sk_ASYNC_JOB_push(pool->jobs, job); -} - -void async_start_func(void) -{ - ASYNC_JOB *job; - async_ctx *ctx = async_get_ctx(); - - while (1) { - /* Run the job */ - job = ctx->currjob; - job->ret = job->func(job->funcargs); - - /* Stop the job */ - job->status = ASYNC_JOB_STOPPING; - if (!async_fibre_swapcontext(&job->fibrectx, - &ctx->dispatcher, 1)) { - /* - * Should not happen. Getting here will close the thread...can't do - * much about it - */ - ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); - } - } -} - -int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, - int (*func)(void *), void *args, size_t size) -{ - async_ctx *ctx; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return ASYNC_ERR; - - ctx = async_get_ctx(); - if (ctx == NULL) - ctx = async_ctx_new(); - if (ctx == NULL) - return ASYNC_ERR; - - if (*job) - ctx->currjob = *job; - - for (;;) { - if (ctx->currjob != NULL) { - if (ctx->currjob->status == ASYNC_JOB_STOPPING) { - *ret = ctx->currjob->ret; - ctx->currjob->waitctx = NULL; - async_release_job(ctx->currjob); - ctx->currjob = NULL; - *job = NULL; - return ASYNC_FINISH; - } - - if (ctx->currjob->status == ASYNC_JOB_PAUSING) { - *job = ctx->currjob; - ctx->currjob->status = ASYNC_JOB_PAUSED; - ctx->currjob = NULL; - return ASYNC_PAUSE; - } - - if (ctx->currjob->status == ASYNC_JOB_PAUSED) { - ctx->currjob = *job; - /* Resume previous job */ - if (!async_fibre_swapcontext(&ctx->dispatcher, - &ctx->currjob->fibrectx, 1)) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, - ASYNC_R_FAILED_TO_SWAP_CONTEXT); - goto err; - } - continue; - } - - /* Should not happen */ - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR); - async_release_job(ctx->currjob); - ctx->currjob = NULL; - *job = NULL; - return ASYNC_ERR; - } - - /* Start a new job */ - if ((ctx->currjob = async_get_pool_job()) == NULL) - return ASYNC_NO_JOBS; - - if (args != NULL) { - ctx->currjob->funcargs = OPENSSL_malloc(size); - if (ctx->currjob->funcargs == NULL) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE); - async_release_job(ctx->currjob); - ctx->currjob = NULL; - return ASYNC_ERR; - } - memcpy(ctx->currjob->funcargs, args, size); - } else { - ctx->currjob->funcargs = NULL; - } - - ctx->currjob->func = func; - ctx->currjob->waitctx = wctx; - if (!async_fibre_swapcontext(&ctx->dispatcher, - &ctx->currjob->fibrectx, 1)) { - ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); - goto err; - } - } - -err: - async_release_job(ctx->currjob); - ctx->currjob = NULL; - *job = NULL; - return ASYNC_ERR; -} - -int ASYNC_pause_job(void) -{ - ASYNC_JOB *job; - async_ctx *ctx = async_get_ctx(); - - if (ctx == NULL - || ctx->currjob == NULL - || ctx->blocked) { - /* - * Could be we've deliberately not been started within a job so this is - * counted as success. - */ - return 1; - } - - job = ctx->currjob; - job->status = ASYNC_JOB_PAUSING; - - if (!async_fibre_swapcontext(&job->fibrectx, - &ctx->dispatcher, 1)) { - ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); - return 0; - } - /* Reset counts of added and deleted fds */ - async_wait_ctx_reset_counts(job->waitctx); - - return 1; -} - -static void async_empty_pool(async_pool *pool) -{ - ASYNC_JOB *job; - - if (!pool || !pool->jobs) - return; - - do { - job = sk_ASYNC_JOB_pop(pool->jobs); - async_job_free(job); - } while (job); -} - -int async_init(void) -{ - if (!CRYPTO_THREAD_init_local(&ctxkey, NULL)) - return 0; - - if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) { - CRYPTO_THREAD_cleanup_local(&ctxkey); - return 0; - } - - return 1; -} - -void async_deinit(void) -{ - CRYPTO_THREAD_cleanup_local(&ctxkey); - CRYPTO_THREAD_cleanup_local(&poolkey); -} - -int ASYNC_init_thread(size_t max_size, size_t init_size) -{ - async_pool *pool; - size_t curr_size = 0; - - if (init_size > max_size) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); - return 0; - } - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return 0; - - if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) - return 0; - - pool = OPENSSL_zalloc(sizeof(*pool)); - if (pool == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); - return 0; - } - - pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); - if (pool->jobs == NULL) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); - OPENSSL_free(pool); - return 0; - } - - pool->max_size = max_size; - - /* Pre-create jobs as required */ - while (init_size--) { - ASYNC_JOB *job; - job = async_job_new(); - if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) { - /* - * Not actually fatal because we already created the pool, just - * skip creation of any more jobs - */ - async_job_free(job); - break; - } - job->funcargs = NULL; - sk_ASYNC_JOB_push(pool->jobs, job); /* Cannot fail due to reserve */ - curr_size++; - } - pool->curr_size = curr_size; - if (!CRYPTO_THREAD_set_local(&poolkey, pool)) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); - goto err; - } - - return 1; -err: - async_empty_pool(pool); - sk_ASYNC_JOB_free(pool->jobs); - OPENSSL_free(pool); - return 0; -} - -void async_delete_thread_state(void) -{ - async_pool *pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); - - if (pool != NULL) { - async_empty_pool(pool); - sk_ASYNC_JOB_free(pool->jobs); - OPENSSL_free(pool); - CRYPTO_THREAD_set_local(&poolkey, NULL); - } - async_local_cleanup(); - async_ctx_free(); -} - -void ASYNC_cleanup_thread(void) -{ - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return; - - async_delete_thread_state(); -} - -ASYNC_JOB *ASYNC_get_current_job(void) -{ - async_ctx *ctx; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return NULL; - - ctx = async_get_ctx(); - if (ctx == NULL) - return NULL; - - return ctx->currjob; -} - -ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job) -{ - return job->waitctx; -} - -void ASYNC_block_pause(void) -{ - async_ctx *ctx; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return; - - ctx = async_get_ctx(); - if (ctx == NULL || ctx->currjob == NULL) { - /* - * We're not in a job anyway so ignore this - */ - return; - } - ctx->blocked++; -} - -void ASYNC_unblock_pause(void) -{ - async_ctx *ctx; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) - return; - - ctx = async_get_ctx(); - if (ctx == NULL || ctx->currjob == NULL) { - /* - * We're not in a job anyway so ignore this - */ - return; - } - if (ctx->blocked > 0) - ctx->blocked--; -} +#include <string.h> + +#define ASYNC_JOB_RUNNING 0 +#define ASYNC_JOB_PAUSING 1 +#define ASYNC_JOB_PAUSED 2 +#define ASYNC_JOB_STOPPING 3 + +static CRYPTO_THREAD_LOCAL ctxkey; +static CRYPTO_THREAD_LOCAL poolkey; + +static async_ctx *async_ctx_new(void) +{ + async_ctx *nctx; + + if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) + return NULL; + + nctx = OPENSSL_malloc(sizeof(*nctx)); + if (nctx == NULL) { + ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE); + goto err; + } + + async_fibre_init_dispatcher(&nctx->dispatcher); + nctx->currjob = NULL; + nctx->blocked = 0; + if (!CRYPTO_THREAD_set_local(&ctxkey, nctx)) + goto err; + + return nctx; +err: + OPENSSL_free(nctx); + + return NULL; +} + +async_ctx *async_get_ctx(void) +{ + return (async_ctx *)CRYPTO_THREAD_get_local(&ctxkey); +} + +static int async_ctx_free(void) +{ + async_ctx *ctx; + + ctx = async_get_ctx(); + + if (!CRYPTO_THREAD_set_local(&ctxkey, NULL)) + return 0; + + OPENSSL_free(ctx); + + return 1; +} + +static ASYNC_JOB *async_job_new(void) +{ + ASYNC_JOB *job = NULL; + + job = OPENSSL_zalloc(sizeof(*job)); + if (job == NULL) { + ASYNCerr(ASYNC_F_ASYNC_JOB_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + job->status = ASYNC_JOB_RUNNING; + + return job; +} + +static void async_job_free(ASYNC_JOB *job) +{ + if (job != NULL) { + OPENSSL_free(job->funcargs); + async_fibre_free(&job->fibrectx); + OPENSSL_free(job); + } +} + +static ASYNC_JOB *async_get_pool_job(void) { + ASYNC_JOB *job; + async_pool *pool; + + pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); + if (pool == NULL) { + /* + * Pool has not been initialised, so init with the defaults, i.e. + * no max size and no pre-created jobs + */ + if (ASYNC_init_thread(0, 0) == 0) + return NULL; + pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); + } + + job = sk_ASYNC_JOB_pop(pool->jobs); + if (job == NULL) { + /* Pool is empty */ + if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size)) + return NULL; + + job = async_job_new(); + if (job != NULL) { + if (! async_fibre_makecontext(&job->fibrectx)) { + async_job_free(job); + return NULL; + } + pool->curr_size++; + } + } + return job; +} + +static void async_release_job(ASYNC_JOB *job) { + async_pool *pool; + + pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); + OPENSSL_free(job->funcargs); + job->funcargs = NULL; + sk_ASYNC_JOB_push(pool->jobs, job); +} + +void async_start_func(void) +{ + ASYNC_JOB *job; + async_ctx *ctx = async_get_ctx(); + + while (1) { + /* Run the job */ + job = ctx->currjob; + job->ret = job->func(job->funcargs); + + /* Stop the job */ + job->status = ASYNC_JOB_STOPPING; + if (!async_fibre_swapcontext(&job->fibrectx, + &ctx->dispatcher, 1)) { + /* + * Should not happen. Getting here will close the thread...can't do + * much about it + */ + ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + } + } +} + +int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, + int (*func)(void *), void *args, size_t size) +{ + async_ctx *ctx; + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return ASYNC_ERR; + + ctx = async_get_ctx(); + if (ctx == NULL) + ctx = async_ctx_new(); + if (ctx == NULL) + return ASYNC_ERR; + + if (*job) + ctx->currjob = *job; + + for (;;) { + if (ctx->currjob != NULL) { + if (ctx->currjob->status == ASYNC_JOB_STOPPING) { + *ret = ctx->currjob->ret; + ctx->currjob->waitctx = NULL; + async_release_job(ctx->currjob); + ctx->currjob = NULL; + *job = NULL; + return ASYNC_FINISH; + } + + if (ctx->currjob->status == ASYNC_JOB_PAUSING) { + *job = ctx->currjob; + ctx->currjob->status = ASYNC_JOB_PAUSED; + ctx->currjob = NULL; + return ASYNC_PAUSE; + } + + if (ctx->currjob->status == ASYNC_JOB_PAUSED) { + ctx->currjob = *job; + /* Resume previous job */ + if (!async_fibre_swapcontext(&ctx->dispatcher, + &ctx->currjob->fibrectx, 1)) { + ASYNCerr(ASYNC_F_ASYNC_START_JOB, + ASYNC_R_FAILED_TO_SWAP_CONTEXT); + goto err; + } + continue; + } + + /* Should not happen */ + ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR); + async_release_job(ctx->currjob); + ctx->currjob = NULL; + *job = NULL; + return ASYNC_ERR; + } + + /* Start a new job */ + if ((ctx->currjob = async_get_pool_job()) == NULL) + return ASYNC_NO_JOBS; + + if (args != NULL) { + ctx->currjob->funcargs = OPENSSL_malloc(size); + if (ctx->currjob->funcargs == NULL) { + ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE); + async_release_job(ctx->currjob); + ctx->currjob = NULL; + return ASYNC_ERR; + } + memcpy(ctx->currjob->funcargs, args, size); + } else { + ctx->currjob->funcargs = NULL; + } + + ctx->currjob->func = func; + ctx->currjob->waitctx = wctx; + if (!async_fibre_swapcontext(&ctx->dispatcher, + &ctx->currjob->fibrectx, 1)) { + ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + goto err; + } + } + +err: + async_release_job(ctx->currjob); + ctx->currjob = NULL; + *job = NULL; + return ASYNC_ERR; +} + +int ASYNC_pause_job(void) +{ + ASYNC_JOB *job; + async_ctx *ctx = async_get_ctx(); + + if (ctx == NULL + || ctx->currjob == NULL + || ctx->blocked) { + /* + * Could be we've deliberately not been started within a job so this is + * counted as success. + */ + return 1; + } + + job = ctx->currjob; + job->status = ASYNC_JOB_PAUSING; + + if (!async_fibre_swapcontext(&job->fibrectx, + &ctx->dispatcher, 1)) { + ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); + return 0; + } + /* Reset counts of added and deleted fds */ + async_wait_ctx_reset_counts(job->waitctx); + + return 1; +} + +static void async_empty_pool(async_pool *pool) +{ + ASYNC_JOB *job; + + if (!pool || !pool->jobs) + return; + + do { + job = sk_ASYNC_JOB_pop(pool->jobs); + async_job_free(job); + } while (job); +} + +int async_init(void) +{ + if (!CRYPTO_THREAD_init_local(&ctxkey, NULL)) + return 0; + + if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) { + CRYPTO_THREAD_cleanup_local(&ctxkey); + return 0; + } + + return 1; +} + +void async_deinit(void) +{ + CRYPTO_THREAD_cleanup_local(&ctxkey); + CRYPTO_THREAD_cleanup_local(&poolkey); +} + +int ASYNC_init_thread(size_t max_size, size_t init_size) +{ + async_pool *pool; + size_t curr_size = 0; + + if (init_size > max_size) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); + return 0; + } + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return 0; + + if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) + return 0; + + pool = OPENSSL_zalloc(sizeof(*pool)); + if (pool == NULL) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); + return 0; + } + + pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); + if (pool->jobs == NULL) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); + OPENSSL_free(pool); + return 0; + } + + pool->max_size = max_size; + + /* Pre-create jobs as required */ + while (init_size--) { + ASYNC_JOB *job; + job = async_job_new(); + if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) { + /* + * Not actually fatal because we already created the pool, just + * skip creation of any more jobs + */ + async_job_free(job); + break; + } + job->funcargs = NULL; + sk_ASYNC_JOB_push(pool->jobs, job); /* Cannot fail due to reserve */ + curr_size++; + } + pool->curr_size = curr_size; + if (!CRYPTO_THREAD_set_local(&poolkey, pool)) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); + goto err; + } + + return 1; +err: + async_empty_pool(pool); + sk_ASYNC_JOB_free(pool->jobs); + OPENSSL_free(pool); + return 0; +} + +void async_delete_thread_state(void) +{ + async_pool *pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey); + + if (pool != NULL) { + async_empty_pool(pool); + sk_ASYNC_JOB_free(pool->jobs); + OPENSSL_free(pool); + CRYPTO_THREAD_set_local(&poolkey, NULL); + } + async_local_cleanup(); + async_ctx_free(); +} + +void ASYNC_cleanup_thread(void) +{ + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return; + + async_delete_thread_state(); +} + +ASYNC_JOB *ASYNC_get_current_job(void) +{ + async_ctx *ctx; + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return NULL; + + ctx = async_get_ctx(); + if (ctx == NULL) + return NULL; + + return ctx->currjob; +} + +ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job) +{ + return job->waitctx; +} + +void ASYNC_block_pause(void) +{ + async_ctx *ctx; + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return; + + ctx = async_get_ctx(); + if (ctx == NULL || ctx->currjob == NULL) { + /* + * We're not in a job anyway so ignore this + */ + return; + } + ctx->blocked++; +} + +void ASYNC_unblock_pause(void) +{ + async_ctx *ctx; + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return; + + ctx = async_get_ctx(); + if (ctx == NULL || ctx->currjob == NULL) { + /* + * We're not in a job anyway so ignore this + */ + return; + } + if (ctx->blocked > 0) + ctx->blocked--; +} diff --git a/contrib/libs/openssl/crypto/async/async_err.c b/contrib/libs/openssl/crypto/async/async_err.c index 36bba0c762..fd5527aae8 100644 --- a/contrib/libs/openssl/crypto/async/async_err.c +++ b/contrib/libs/openssl/crypto/async/async_err.c @@ -1,51 +1,51 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - -#include <openssl/err.h> -#include <openssl/asyncerr.h> - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA ASYNC_str_functs[] = { - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_CTX_NEW, 0), "async_ctx_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_INIT_THREAD, 0), - "ASYNC_init_thread"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_JOB_NEW, 0), "async_job_new"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_PAUSE_JOB, 0), "ASYNC_pause_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_FUNC, 0), "async_start_func"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_JOB, 0), "ASYNC_start_job"}, - {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 0), - "ASYNC_WAIT_CTX_set_wait_fd"}, - {0, NULL} -}; - -static const ERR_STRING_DATA ASYNC_str_reasons[] = { - {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SET_POOL), - "failed to set pool"}, - {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SWAP_CONTEXT), - "failed to swap context"}, - {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INIT_FAILED), "init failed"}, - {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INVALID_POOL_SIZE), - "invalid pool size"}, - {0, NULL} -}; - -#endif - -int ERR_load_ASYNC_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) { - ERR_load_strings_const(ASYNC_str_functs); - ERR_load_strings_const(ASYNC_str_reasons); - } -#endif - return 1; -} +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + +#include <openssl/err.h> +#include <openssl/asyncerr.h> + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA ASYNC_str_functs[] = { + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_CTX_NEW, 0), "async_ctx_new"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_INIT_THREAD, 0), + "ASYNC_init_thread"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_JOB_NEW, 0), "async_job_new"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_PAUSE_JOB, 0), "ASYNC_pause_job"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_FUNC, 0), "async_start_func"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_START_JOB, 0), "ASYNC_start_job"}, + {ERR_PACK(ERR_LIB_ASYNC, ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 0), + "ASYNC_WAIT_CTX_set_wait_fd"}, + {0, NULL} +}; + +static const ERR_STRING_DATA ASYNC_str_reasons[] = { + {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SET_POOL), + "failed to set pool"}, + {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SWAP_CONTEXT), + "failed to swap context"}, + {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INIT_FAILED), "init failed"}, + {ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INVALID_POOL_SIZE), + "invalid pool size"}, + {0, NULL} +}; + +#endif + +int ERR_load_ASYNC_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) { + ERR_load_strings_const(ASYNC_str_functs); + ERR_load_strings_const(ASYNC_str_reasons); + } +#endif + return 1; +} diff --git a/contrib/libs/openssl/crypto/async/async_wait.c b/contrib/libs/openssl/crypto/async/async_wait.c index 38028ab380..7723f949a6 100644 --- a/contrib/libs/openssl/crypto/async/async_wait.c +++ b/contrib/libs/openssl/crypto/async/async_wait.c @@ -1,213 +1,213 @@ -/* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 */ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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) { - ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 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; -} - -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; - } -} + +#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) { + ASYNCerr(ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD, 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; +} + +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; + } +} |