diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/e_dasync.c | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/engines/e_dasync.c b/engines/e_dasync.c index cca9f5e3e9..0580103d23 100644 --- a/engines/e_dasync.c +++ b/engines/e_dasync.c @@ -61,6 +61,16 @@ #include <openssl/bn.h> #include <openssl/crypto.h> +#if (defined(OPENSSL_SYS_UNIX) || defined(OPENSSL_SYS_CYGWIN)) && defined(OPENSSL_THREADS) +# undef ASYNC_POSIX +# define ASYNC_POSIX +# include <unistd.h> +#elif defined(_WIN32) +# undef ASYNC_WIN +# define ASYNC_WIN +# include <windows.h> +#endif + #define DASYNC_LIB_NAME "DASYNC" #include "e_dasync_err.c" @@ -261,26 +271,87 @@ static int dasync_digests(ENGINE *e, const EVP_MD **digest, return ok; } +static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD readfd, void *pvwritefd) +{ + OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd; +#if defined(ASYNC_WIN) + CloseHandle(readfd); + CloseHandle(*pwritefd); +#elif defined(ASYNC_POSIX) + close(readfd); + close(*pwritefd); +#endif + OPENSSL_free(pwritefd); +} + +#define DUMMY_CHAR 'X' + static void dummy_pause_job(void) { ASYNC_JOB *job; + ASYNC_WAIT_CTX *waitctx; + OSSL_ASYNC_FD pipefds[2] = {0, 0}; + OSSL_ASYNC_FD *writefd; +#if defined(ASYNC_WIN) + DWORD numwritten, numread; + char buf = DUMMY_CHAR; +#elif defined(ASYNC_POSIX) + char buf = DUMMY_CHAR; +#endif if ((job = ASYNC_get_current_job()) == NULL) return; + waitctx = ASYNC_get_wait_ctx(job); + + if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0], + (void **)&writefd)) { + pipefds[1] = *writefd; + } else { + writefd = OPENSSL_malloc(sizeof(*writefd)); + if (writefd == NULL) + return; +#if defined(ASYNC_WIN) + if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) { + OPENSSL_free(writefd); + return; + } +#elif defined(ASYNC_POSIX) + if (pipe(pipefds) != 0) { + OPENSSL_free(writefd); + return; + } +#endif + *writefd = pipefds[1]; + + if(!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0], + writefd, wait_cleanup)) { + wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd); + return; + } + } /* * In the Dummy async engine we are cheating. We signal that the job * is complete by waking it before the call to ASYNC_pause_job(). A real * async engine would only wake when the job was actually complete */ - ASYNC_wake(job); +#if defined(ASYNC_WIN) + WriteFile(pipefds[1], &buf, 1, &numwritten, NULL); +#elif defined(ASYNC_POSIX) + write(pipefds[1], &buf, 1); +#endif /* Ignore errors - we carry on anyway */ ASYNC_pause_job(); - ASYNC_clear_wake(job); + /* Clear the wake signal */ +#if defined(ASYNC_WIN) + ReadFile(pipefds[0], &buf, 1, &numread, NULL); +#elif defined(ASYNC_POSIX) + read(pipefds[0], &buf, 1); +#endif } - /* * SHA1 implementation. At the moment we just defer to the standard * implementation |