Define a few internal macros for easy use of run_once functions
authorRichard Levitte <levitte@openssl.org>
Tue, 19 Jul 2016 17:38:57 +0000 (19:38 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 19 Jul 2016 21:49:54 +0000 (23:49 +0200)
Because pthread_once() takes a function taking no argument and
returning nothing, and we want to be able to check if they're
successful, we define a few internal macros to get around the issue.

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
include/internal/thread_once.h [new file with mode: 0644]

diff --git a/include/internal/thread_once.h b/include/internal/thread_once.h
new file mode 100644 (file)
index 0000000..74f6ccb
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1995-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/crypto.h>
+
+#define DEFINE_RUN_ONCE(init)                   \
+    static int init(void);                     \
+    int init##_ossl_ret_ = 0;                   \
+    void init##_ossl_(void)                     \
+    {                                           \
+        init##_ossl_ret_ = init();              \
+    }                                           \
+    static int init(void)
+#define DECLARE_RUN_ONCE(init)                  \
+    extern int init##_ossl_ret_;                \
+    void init##_ossl_(void);
+
+#define DEFINE_RUN_ONCE_STATIC(init)            \
+    static int init(void);                     \
+    static int init##_ossl_ret_ = 0;            \
+    static void init##_ossl_(void)              \
+    {                                           \
+        init##_ossl_ret_ = init();              \
+    }                                           \
+    static int init(void)
+
+/*
+ * RUN_ONCE - use CRYPTO_THREAD_run_once, and check if the init succeeded
+ * @once: pointer to static object of type CRYPTO_ONCE
+ * @init: function name that was previously given to DEFINE_RUN_ONCE,
+ *        DEFINE_RUN_ONCE_STATIC or DECLARE_RUN_ONCE.
+ *
+ * The return value is 1 on success or 0 in case of error.
+ */
+#define RUN_ONCE(once, init)                                            \
+    (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0)