Implement windows async pool and notify support
authorMatt Caswell <matt@openssl.org>
Wed, 16 Sep 2015 22:43:45 +0000 (23:43 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 20 Nov 2015 23:33:46 +0000 (23:33 +0000)
Port the async pool and notify code to windows.

Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/async/Makefile
crypto/async/arch/async_posix.c
crypto/async/arch/async_win.c
crypto/async/arch/async_win.h
crypto/async/async.c
crypto/async/async_locl.h

index c09cb31..4f0b392 100644 (file)
@@ -22,8 +22,7 @@ LIBOBJ=async.o arch/async_posix.o arch/async_win.o
 
 SRC= $(LIBSRC)
 
-EXHEADER= async.h
-HEADER=        $(EXHEADER) async_locl.h arch/async_posix.h arch/async_win.h
+HEADER=        async_locl.h arch/async_posix.h arch/async_win.h arch/async_null.h
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
 
index d85a537..4333c87 100644 (file)
@@ -120,12 +120,13 @@ STACK_OF(ASYNC_JOB) *async_get_pool(void)
     return pool;
 }
 
-void async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
+int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
                     size_t max_size)
 {
     pool = poolin;
     pool_curr_size = curr_size;
     pool_max_size = max_size;
+    return 1;
 }
 
 void async_increment_pool_size(void)
@@ -146,6 +147,7 @@ size_t async_pool_max_size(void)
 void async_release_pool(void)
 {
     sk_ASYNC_JOB_free(pool);
+    pool = NULL;
 }
 
 int async_pool_can_grow(void)
index 23447b0..2afa306 100644 (file)
 #ifdef ASYNC_WIN
 
 # include <windows.h>
-# include "cryptlib.h"
+# include "internal/cryptlib.h"
+
+struct winpool {
+    STACK_OF(ASYNC_JOB) *pool;
+    size_t curr_size;
+    size_t max_size;
+};
 
 void ASYNC_start_func(void);
 
@@ -81,4 +87,94 @@ VOID CALLBACK ASYNC_start_func_win(PVOID unused)
     ASYNC_start_func();
 }
 
+int async_pipe(int *pipefds)
+{
+    if (_pipe(pipefds, 256, _O_BINARY) == 0)
+        return 1;
+
+    return 0;
+}
+
+int async_write1(int fd, const void *buf)
+{
+    if (_write(fd, buf, 1) > 0)
+        return 1;
+
+    return 0;
+}
+
+int async_read1(int fd, void *buf)
+{
+    if (_read(fd, buf, 1) > 0)
+        return 1;
+
+    return 0;
+}
+
+STACK_OF(ASYNC_JOB) *async_get_pool(void)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    return pool->pool;
+}
+
+
+int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
+                    size_t max_size)
+{
+    struct winpool *pool;
+    pool = OPENSSL_malloc(sizeof *pool);
+    if (!pool)
+        return 0;
+
+    pool->pool = poolin;
+    pool->curr_size = curr_size;
+    pool->max_size = max_size;
+    CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL, (void *)pool);
+    return 1;
+}
+
+void async_increment_pool_size(void)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    pool->curr_size++;
+}
+
+void async_release_job_to_pool(ASYNC_JOB *job)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    sk_ASYNC_JOB_push(pool->pool, job);
+}
+
+size_t async_pool_max_size(void)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    return pool->max_size;
+}
+
+void async_release_pool(void)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    sk_ASYNC_JOB_free(pool->pool);
+    OPENSSL_free(pool);
+    CRYPTO_set_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL, NULL);
+}
+
+int async_pool_can_grow(void)
+{
+    struct winpool *pool;
+    pool = (struct winpool *)
+            CRYPTO_get_thread_local(CRYPTO_THREAD_LOCAL_ASYNC_POOL);
+    return (pool->max_size == 0) || (pool->curr_size < pool->max_size);
+}
+
 #endif
index 6c2a310..4ecaa02 100644 (file)
@@ -62,7 +62,7 @@
 # define ASYNC_ARCH
 
 # include <windows.h>
-# include "cryptlib.h"
+# include "internal/cryptlib.h"
 
 typedef struct async_fibre_st {
     LPVOID fibre;
index c1f9b22..ed3ed73 100644 (file)
@@ -295,6 +295,16 @@ int ASYNC_in_job(void)
     return 0;
 }
 
+static void async_empty_pool(STACK_OF(ASYNC_JOB) *pool)
+{
+    ASYNC_JOB *job;
+
+    do {
+        job = sk_ASYNC_JOB_pop(pool);
+        ASYNC_JOB_free(job);
+    } while (job);
+}
+
 int ASYNC_init_pool(size_t max_size, size_t init_size)
 {
     STACK_OF(ASYNC_JOB) *pool;
@@ -326,23 +336,24 @@ int ASYNC_init_pool(size_t max_size, size_t init_size)
         }
     }
 
-    async_set_pool(pool, curr_size, max_size);
+    if (!async_set_pool(pool, curr_size, max_size)) {
+        async_empty_pool(pool);
+        sk_ASYNC_JOB_free(pool);
+        return 0;
+    }
 
     return 1;
 }
 
 void ASYNC_free_pool(void)
 {
-    ASYNC_JOB *job;
     STACK_OF(ASYNC_JOB) *pool;
 
     pool = async_get_pool();
     if (pool == NULL)
         return;
-    do {
-        job = sk_ASYNC_JOB_pop(pool);
-        ASYNC_JOB_free(job);
-    } while (job);
+
+    async_empty_pool(pool);
     async_release_pool();
 }
 
index 4bfc37f..ad85fa0 100644 (file)
@@ -80,8 +80,8 @@ DECLARE_STACK_OF(ASYNC_JOB)
 
 void ASYNC_start_func(void);
 STACK_OF(ASYNC_JOB) *async_get_pool(void);
-void async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
-                    size_t max_size);
+int async_set_pool(STACK_OF(ASYNC_JOB) *poolin, size_t curr_size,
+                   size_t max_size);
 void async_increment_pool_size(void);
 void async_release_job_to_pool(ASYNC_JOB *job);
 size_t async_pool_max_size(void);