diff options
Diffstat (limited to 'ext/openssl/ossl_bn.c')
-rw-r--r-- | ext/openssl/ossl_bn.c | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index f3f2e792..bec37299 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -10,6 +10,10 @@ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */ #include "ossl.h" +#if HAVE_RB_EXT_RACTOR_SAFE +#include <ruby/ractor.h> +#endif + #define NewBN(klass) \ TypedData_Wrap_Struct((klass), &ossl_bn_type, 0) #define SetBN(obj, bn) do { \ @@ -150,12 +154,58 @@ ossl_bn_value_ptr(volatile VALUE *ptr) /* * Private */ -/* - * BN_CTX - is used in more difficult math. ops - * (Why just 1? Because Ruby itself isn't thread safe, - * we don't need to care about threads) - */ -BN_CTX *ossl_bn_ctx; + +#if HAVE_RB_EXT_RACTOR_SAFE +void +ossl_bn_ctx_free(void *ptr) +{ + BN_CTX *ctx = (BN_CTX *)ptr; + BN_CTX_free(ctx); +} + +struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = { + NULL, // mark + ossl_bn_ctx_free, +}; + +rb_ractor_local_key_t ossl_bn_ctx_key; + +BN_CTX * +ossl_bn_ctx_get(void) +{ + // stored in ractor local storage + + BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key); + if (!ctx) { + if (!(ctx = BN_CTX_new())) { + ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); + } + rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx); + } + return ctx; +} +#else +// for ruby 2.x +static BN_CTX *gv_ossl_bn_ctx; + +BN_CTX * +ossl_bn_ctx_get(void) +{ + if (gv_ossl_bn_ctx == NULL) { + if (!(gv_ossl_bn_ctx = BN_CTX_new())) { + ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); + } + } + return gv_ossl_bn_ctx; +} + +void +ossl_bn_ctx_free(void) +{ + BN_CTX_free(gv_ossl_bn_ctx); + gv_ossl_bn_ctx = NULL; +} +#endif static VALUE ossl_bn_alloc(VALUE klass) @@ -1102,9 +1152,11 @@ Init_ossl_bn(void) eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); #endif - if (!(ossl_bn_ctx = BN_CTX_new())) { - ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); - } +#ifdef HAVE_RB_EXT_RACTOR_SAFE + ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type); +#else + ossl_bn_ctx_get(); +#endif eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError); |