Async port to windows
authorMatt Caswell <matt@openssl.org>
Tue, 17 Feb 2015 13:30:22 +0000 (13:30 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 20 Nov 2015 23:32:18 +0000 (23:32 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/async/Makefile
crypto/async/arch/async_posix.c [new file with mode: 0644]
crypto/async/arch/async_posix.h [new file with mode: 0644]
crypto/async/arch/async_win.c [new file with mode: 0644]
crypto/async/arch/async_win.h [new file with mode: 0644]
crypto/async/async.c
crypto/async/async_locl.h [new file with mode: 0644]
include/openssl/async.h
util/indent.pro
util/libeay.num

index 2eaaa7d..25b4f93 100644 (file)
@@ -17,13 +17,13 @@ TEST=
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC=async.c
-LIBOBJ=async.o
+LIBSRC=async.c arch/async_posix.c arch/async_win.c
+LIBOBJ=async.o arch/async_posix.o arch/async_win.o
 
 SRC= $(LIBSRC)
 
 EXHEADER= async.h
-HEADER=        $(EXHEADER)
+HEADER=        $(EXHEADER) async_locl.h arch/async_posix.h arch/async_win.h
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
 
@@ -73,11 +73,26 @@ dclean:
 
 clean:
        rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+       rm -f arch/*.o arch/*.obj arch/lib arch/tags arch/core arch/.pure arch/.nfs* arch/*.old arch/*.bak arch/fluff
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
+arch/async_posix.o: ../../include/openssl/async.h
+arch/async_posix.o: ../../include/openssl/crypto.h
+arch/async_posix.o: ../../include/openssl/e_os2.h
+arch/async_posix.o: ../../include/openssl/opensslconf.h
+arch/async_posix.o: ../../include/openssl/opensslv.h
+arch/async_posix.o: ../../include/openssl/ossl_typ.h
+arch/async_posix.o: ../../include/openssl/safestack.h
+arch/async_posix.o: ../../include/openssl/stack.h
+arch/async_posix.o: ../../include/openssl/symhacks.h arch/../arch/async_posix.h
+arch/async_posix.o: arch/../arch/async_win.h arch/../async_locl.h
+arch/async_posix.o: arch/async_posix.c
+arch/async_win.o: ../../include/openssl/async.h arch/async_win.c
+arch/async_win.o: arch/async_win.h
 async.o: ../../include/openssl/async.h ../../include/openssl/crypto.h
 async.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
 async.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 async.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-async.o: ../../include/openssl/symhacks.h async.c
+async.o: ../../include/openssl/symhacks.h arch/async_posix.h arch/async_win.h
+async.o: async.c async_locl.h
diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c
new file mode 100644 (file)
index 0000000..281f25f
--- /dev/null
@@ -0,0 +1,85 @@
+/* crypto/async/arch/async_posix.c */
+/*
+ * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "../async_locl.h"
+#include <openssl/async.h>
+
+#ifdef ASYNC_SYSV
+# include <stddef.h>
+# include <ucontext.h>
+# include <openssl/crypto.h>
+# include <openssl/async.h>
+
+__thread ASYNC_CTX *sysvctx;
+
+int ASYNC_FIBRE_init(ASYNC_FIBRE *fibre)
+{
+    void *stack = NULL;
+
+    if (!(stack = OPENSSL_malloc(SIGSTKSZ))) {
+        return 0;
+    }
+
+    fibre->fibre.uc_stack.ss_sp = stack;
+    fibre->fibre.uc_stack.ss_size = SIGSTKSZ;
+    fibre->fibre.uc_link = NULL;
+
+    return 1;
+}
+
+void ASYNC_FIBRE_free(ASYNC_FIBRE *fibre)
+{
+    if (fibre->fibre.uc_stack.ss_sp)
+        OPENSSL_free(fibre->fibre.uc_stack.ss_sp);
+}
+#endif
diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h
new file mode 100644 (file)
index 0000000..373ad1b
--- /dev/null
@@ -0,0 +1,89 @@
+/* crypto/async/arch/async_posix.h */
+/*
+ * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_SYS_UNIX
+
+# include <unistd.h>
+
+# if _POSIX_VERSION >= 200112L
+
+#  define ASYNC_SYSV
+#  define ASYNC_ARCH
+
+#  include <ucontext.h>
+
+extern __thread ASYNC_CTX *sysvctx;
+
+typedef struct async_fibre_st {
+    ucontext_t fibre;
+} ASYNC_FIBRE;
+
+#  define ASYNC_set_ctx(nctx)             (sysvctx = (nctx))
+#  define ASYNC_get_ctx()                 (sysvctx)
+#  define ASYNC_FIBRE_swapcontext(o,n,r) \
+            ((r)? \
+                !swapcontext(&(o)->fibre, &(n)->fibre) \
+            : \
+                !setcontext(&(n)->fibre))
+#  define ASYNC_FIBRE_makecontext(c) \
+            (ASYNC_FIBRE_init(c) \
+            && !getcontext(&(c)->fibre) \
+            && (makecontext(&(c)->fibre, ASYNC_start_func, 0), 1))
+#  define ASYNC_FIBRE_init_dispatcher(d)
+
+int ASYNC_FIBRE_init(ASYNC_FIBRE *fibre);
+void ASYNC_FIBRE_free(ASYNC_FIBRE *fibre);
+
+# endif
+#endif
diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c
new file mode 100644 (file)
index 0000000..23447b0
--- /dev/null
@@ -0,0 +1,84 @@
+/* crypto/async/arch/async_win.c */
+/*
+ * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "async_win.h"
+
+#ifdef ASYNC_WIN
+
+# include <windows.h>
+# include "cryptlib.h"
+
+void ASYNC_start_func(void);
+
+int ASYNC_FIBRE_init_dispatcher(ASYNC_FIBRE *fibre)
+{
+    LPVOID dispatcher;
+
+    dispatcher =
+        (LPVOID) CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_DISPATCH);
+    if (!dispatcher) {
+        fibre->fibre = ConvertThreadToFiber(NULL);
+        CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_DISPATCH,
+                                (void *)fibre->fibre);
+    } else {
+        fibre->fibre = dispatcher;
+    }
+    return 1;
+}
+
+VOID CALLBACK ASYNC_start_func_win(PVOID unused)
+{
+    ASYNC_start_func();
+}
+
+#endif
diff --git a/crypto/async/arch/async_win.h b/crypto/async/arch/async_win.h
new file mode 100644 (file)
index 0000000..6c2a310
--- /dev/null
@@ -0,0 +1,84 @@
+/* crypto/async/arch/async_win.h */
+/*
+ * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/async.h>
+
+/*
+ * 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(__CYGWIN__)
+# define ASYNC_WIN
+# define ASYNC_ARCH
+
+# include <windows.h>
+# include "cryptlib.h"
+
+typedef struct async_fibre_st {
+    LPVOID fibre;
+} ASYNC_FIBRE;
+
+# define ASYNC_set_ctx(nctx) \
+        (CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_CTX, (void *)(nctx)))
+# define ASYNC_get_ctx() \
+        ((ASYNC_CTX *)CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_CTX))
+# 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
index 2f6eca1..9b044d3 100644 (file)
@@ -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
 #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;
diff --git a/crypto/async/async_locl.h b/crypto/async/async_locl.h
new file mode 100644 (file)
index 0000000..fefe62a
--- /dev/null
@@ -0,0 +1,78 @@
+/* crypto/async/async_locl.h */
+/*
+ * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/async.h>
+
+typedef struct async_ctx_st ASYNC_CTX;
+
+#include "arch/async_win.h"
+#include "arch/async_posix.h"
+
+#ifndef ASYNC_ARCH
+# error Failed to detect async arch
+#endif
+
+struct async_ctx_st {
+    ASYNC_FIBRE dispatcher;
+    ASYNC_JOB *currjob;
+};
+
+struct async_job_st {
+    ASYNC_FIBRE fibrectx;
+    int (*func) (void *);
+    void *funcargs;
+    int ret;
+    int status;
+};
+
+void ASYNC_start_func(void);
index bf5a021..434db22 100644 (file)
@@ -54,6 +54,8 @@
 #ifndef HEADER_ASYNC_H
 # define HEADER_ASYNC_H
 
+#include <stdlib.h>
+
 # ifdef  __cplusplus
 extern "C" {
 # endif
index 4d1bd45..abfccc7 100644 (file)
 -T SH_LIST
 -T PACKET
 -T RECORD_LAYER
+-T ASYNC_FIBRE
+-T ASYNC_CTX
+-T ASYNC_JOB
index 5d72034..48ffd71 100755 (executable)
@@ -4650,3 +4650,7 @@ X509_aux_print                          5009      EXIST::FUNCTION:STDIO
 TS_RESP_CTX_set_signer_digest           5010   EXIST::FUNCTION:
 TS_CONF_set_signer_digest               5011   EXIST::FUNCTION:
 ENGINE_load_dasync                      5012   EXIST::FUNCTION:ENGINE,STATIC_ENGINE
+ASYNC_pause_job                         5013   EXIST::FUNCTION:
+ASYNC_job_is_waiting                    5014   EXIST::FUNCTION:
+ASYNC_in_job                            5015   EXIST::FUNCTION:
+ASYNC_start_job                         5016   EXIST::FUNCTION: