aboutsummaryrefslogtreecommitdiff
path: root/crypto/async/async.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2015-02-17 13:30:22 +0000
committerMatt Caswell <matt@openssl.org>2015-11-20 23:32:18 +0000
commit501083049590455b1862edd7573fd51bb37bb037 (patch)
tree0ac76d39b5222fe01e80474bcdd17077796af3a8 /crypto/async/async.c
parent38148a234c6ed7a9d78dc5fb3de0ac4d79402e6f (diff)
downloadopenssl-501083049590455b1862edd7573fd51bb37bb037.zip
openssl-501083049590455b1862edd7573fd51bb37bb037.tar.gz
openssl-501083049590455b1862edd7573fd51bb37bb037.tar.bz2
Async port to windows
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/async/async.c')
-rw-r--r--crypto/async/async.c178
1 files changed, 76 insertions, 102 deletions
diff --git a/crypto/async/async.c b/crypto/async/async.c
index 2f6eca1..9b044d3 100644
--- a/crypto/async/async.c
+++ b/crypto/async/async.c
@@ -53,8 +53,8 @@
#include <openssl/crypto.h>
#include <openssl/async.h>
-#include <ucontext.h>
#include <string.h>
+#include "async_locl.h"
#define ASYNC_JOB_RUNNING 0
#define ASYNC_JOB_PAUSING 1
@@ -62,22 +62,6 @@
#define ASYNC_JOB_STOPPING 3
-typedef struct async_ctx_st {
- ucontext_t dispatcher;
- ASYNC_JOB *currjob;
-} ASYNC_CTX;
-
-__thread ASYNC_CTX *ctx;
-
-struct async_job_st {
- ucontext_t fibrectx;
- int (*func)(void *);
- void *funcargs;
- int ret;
- int status;
-};
-
-
static ASYNC_CTX *ASYNC_CTX_new(void)
{
ASYNC_CTX *nctx = NULL;
@@ -87,8 +71,9 @@ static ASYNC_CTX *ASYNC_CTX_new(void)
goto err;
}
+ ASYNC_FIBRE_init_dispatcher(&nctx->dispatcher);
nctx->currjob = NULL;
- ctx = nctx;
+ ASYNC_set_ctx(nctx);
return nctx;
err:
@@ -101,11 +86,11 @@ err:
static int ASYNC_CTX_free(void)
{
- if(ctx) {
- OPENSSL_free(ctx);
+ if(ASYNC_get_ctx()) {
+ OPENSSL_free(ASYNC_get_ctx());
}
- ctx = NULL;
+ ASYNC_set_ctx(NULL);
return 1;
}
@@ -113,31 +98,15 @@ static int ASYNC_CTX_free(void)
static ASYNC_JOB *ASYNC_JOB_new(void)
{
ASYNC_JOB *job = NULL;
- void *stack = NULL;
if(!(job = OPENSSL_malloc(sizeof (ASYNC_JOB)))) {
- goto err;
+ return NULL;
}
- if(!(stack = OPENSSL_malloc(SIGSTKSZ))) {
- goto err;
- }
- if(getcontext(&job->fibrectx))
- goto err;
- job->fibrectx.uc_stack.ss_sp = stack;
- job->fibrectx.uc_stack.ss_size = SIGSTKSZ;
- job->fibrectx.uc_link = NULL;
job->status = ASYNC_JOB_RUNNING;
job->funcargs = NULL;
return job;
-err:
- if(job) {
- if(stack)
- OPENSSL_free(stack);
- OPENSSL_free(job);
- }
- return NULL;
}
static void ASYNC_JOB_free(ASYNC_JOB *job)
@@ -145,99 +114,103 @@ static void ASYNC_JOB_free(ASYNC_JOB *job)
if(job) {
if(job->funcargs)
OPENSSL_free(job->funcargs);
- if(job->fibrectx.uc_stack.ss_sp)
- OPENSSL_free(job->fibrectx.uc_stack.ss_sp);
+ ASYNC_FIBRE_free(&job->fibrectx);
OPENSSL_free(job);
}
}
-static void ASYNC_start_func(void)
+void ASYNC_start_func(void)
{
ASYNC_JOB *job;
/* Run the job */
- job = ctx->currjob;
+ job = ASYNC_get_ctx()->currjob;
job->ret = job->func(job->funcargs);
/* Stop the job */
job->status = ASYNC_JOB_STOPPING;
- setcontext(&ctx->dispatcher);
-
- /*
- * Should not happen. Getting here will close the thread...can't do much
- * about it
- */
+ if(!ASYNC_FIBRE_swapcontext(&job->fibrectx,
+ &ASYNC_get_ctx()->dispatcher, 0)) {
+ /*
+ * Should not happen. Getting here will close the thread...can't do much
+ * about it
+ */
+ }
}
int ASYNC_start_job(ASYNC_JOB **job, int *ret, int (*func)(void *),
void *args, size_t size)
{
- if(ctx || !ASYNC_CTX_new()) {
+ if(ASYNC_get_ctx() || !ASYNC_CTX_new()) {
return ASYNC_ERR;
}
if(*job) {
- ctx->currjob = *job;
+ ASYNC_get_ctx()->currjob = *job;
}
- getcontext(&ctx->dispatcher);
-
- if(ctx->currjob) {
- if(ctx->currjob->status == ASYNC_JOB_STOPPING) {
- *ret = ctx->currjob->ret;
- ASYNC_JOB_free(ctx->currjob);
- ctx->currjob = NULL;
+ for (;;) {
+ if(ASYNC_get_ctx()->currjob) {
+ if(ASYNC_get_ctx()->currjob->status == ASYNC_JOB_STOPPING) {
+ *ret = ASYNC_get_ctx()->currjob->ret;
+ ASYNC_JOB_free(ASYNC_get_ctx()->currjob);
+ ASYNC_get_ctx()->currjob = NULL;
+ ASYNC_CTX_free();
+ return ASYNC_FINISH;
+ }
+
+ if(ASYNC_get_ctx()->currjob->status == ASYNC_JOB_PAUSING) {
+ *job = ASYNC_get_ctx()->currjob;
+ ASYNC_get_ctx()->currjob->status = ASYNC_JOB_PAUSED;
+ ASYNC_CTX_free();
+ return ASYNC_PAUSE;
+ }
+
+ if(ASYNC_get_ctx()->currjob->status == ASYNC_JOB_PAUSED) {
+ ASYNC_get_ctx()->currjob = *job;
+ /* Resume previous job */
+ if(!ASYNC_FIBRE_swapcontext(&ASYNC_get_ctx()->dispatcher,
+ &ASYNC_get_ctx()->currjob->fibrectx, 1))
+ goto err;
+ continue;
+ }
+
+ /* Should not happen */
+ ASYNC_JOB_free(ASYNC_get_ctx()->currjob);
+ ASYNC_get_ctx()->currjob = NULL;
ASYNC_CTX_free();
- return ASYNC_FINISH;
+ return ASYNC_ERR;
}
- if(ctx->currjob->status == ASYNC_JOB_PAUSING) {
- *job = ctx->currjob;
- ctx->currjob->status = ASYNC_JOB_PAUSED;
+ /* Start a new job */
+ if(!(ASYNC_get_ctx()->currjob = ASYNC_JOB_new())) {
ASYNC_CTX_free();
- return ASYNC_PAUSE;
+ return ASYNC_ERR;
}
- if(ctx->currjob->status == ASYNC_JOB_PAUSED) {
- ctx->currjob = *job;
- /* Resume previous job */
- setcontext(&ctx->currjob->fibrectx);
- /* Does not return */
+ if(args != NULL) {
+ ASYNC_get_ctx()->currjob->funcargs = OPENSSL_malloc(size);
+ if(!ASYNC_get_ctx()->currjob->funcargs) {
+ ASYNC_JOB_free(ASYNC_get_ctx()->currjob);
+ ASYNC_get_ctx()->currjob = NULL;
+ ASYNC_CTX_free();
+ return ASYNC_ERR;
+ }
+ memcpy(ASYNC_get_ctx()->currjob->funcargs, args, size);
+ } else {
+ ASYNC_get_ctx()->currjob->funcargs = NULL;
}
- /* Should not happen */
- ASYNC_JOB_free(ctx->currjob);
- ctx->currjob = NULL;
- ASYNC_CTX_free();
- return ASYNC_ERR;
- }
-
- /* Start a new job */
- if(!(ctx->currjob = ASYNC_JOB_new())) {
- ASYNC_CTX_free();
- return ASYNC_ERR;
- }
-
- if(args != NULL) {
- ctx->currjob->funcargs = OPENSSL_malloc(size);
- if(!ctx->currjob->funcargs) {
- ASYNC_JOB_free(ctx->currjob);
- ctx->currjob = NULL;
- ASYNC_CTX_free();
- return ASYNC_ERR;
- }
- memcpy(ctx->currjob->funcargs, args, size);
- } else {
- ctx->currjob->funcargs = NULL;
+ ASYNC_get_ctx()->currjob->func = func;
+ ASYNC_FIBRE_makecontext(&ASYNC_get_ctx()->currjob->fibrectx);
+ if(!ASYNC_FIBRE_swapcontext(&ASYNC_get_ctx()->dispatcher,
+ &ASYNC_get_ctx()->currjob->fibrectx, 1))
+ goto err;
}
- ctx->currjob->func = func;
- makecontext(&ctx->currjob->fibrectx, ASYNC_start_func, 0);
- setcontext(&ctx->currjob->fibrectx);
-
- /* Does not return except in error */
- ASYNC_JOB_free(ctx->currjob);
- ctx->currjob = NULL;
+err:
+ ASYNC_JOB_free(ASYNC_get_ctx()->currjob);
+ ASYNC_get_ctx()->currjob = NULL;
ASYNC_CTX_free();
return ASYNC_ERR;
}
@@ -247,13 +220,14 @@ int ASYNC_pause_job(void)
{
ASYNC_JOB *job;
- if(!ctx || !ctx->currjob)
+ if(!ASYNC_get_ctx() || !ASYNC_get_ctx()->currjob)
return 0;
- job = ctx->currjob;
+ job = ASYNC_get_ctx()->currjob;
job->status = ASYNC_JOB_PAUSING;
- if(swapcontext(&job->fibrectx, &ctx->dispatcher)) {
+ if(!ASYNC_FIBRE_swapcontext(&job->fibrectx,
+ &ASYNC_get_ctx()->dispatcher, 1)) {
/* Error */
return 0;
}
@@ -263,7 +237,7 @@ int ASYNC_pause_job(void)
int ASYNC_in_job(void)
{
- if(ctx)
+ if(ASYNC_get_ctx())
return 1;
return 0;