diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2018-07-02 21:28:57 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2018-07-27 05:50:07 +0900 |
commit | 8bb519b11cacd65b6043e5cde007f0765049d283 (patch) | |
tree | 354a02b5d3c5f1e2718e4881d49d58842c71ad99 /ext/openssl/ossl_pkey.c | |
parent | 1f90516e32ecd755d592002585e97cb78752eae2 (diff) | |
download | ruby-openssl-8bb519b11cacd65b6043e5cde007f0765049d283.tar.gz |
pkey: resume key generation after interruptky/pkey-generate-interrupt-resume
Key/parameter generation (OpenSSL::PKey::*.{new,generate}) immediately
aborts when it is done with GVL released (in other words, no block is
given) and the thread is interrupted (e.g., by a signal) during the
operation.
Have ossl_generate_cb_2() acquire GVL and call rb_thread_check_ints()
if needed to process the pending interrupt rather than abort the
operation completely by returning 0.
Reference: https://bugs.ruby-lang.org/issues/14882
Diffstat (limited to 'ext/openssl/ossl_pkey.c')
-rw-r--r-- | ext/openssl/ossl_pkey.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index aad3e2e4..962964ee 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -20,6 +20,21 @@ static ID id_private_q; /* * callback for generating keys */ +static VALUE +call_check_ints0(VALUE arg) +{ + rb_thread_check_ints(); + return Qnil; +} + +static void * +call_check_ints(void *arg) +{ + int state; + rb_protect(call_check_ints0, Qnil, &state); + return (void *)(VALUE)state; +} + int ossl_generate_cb_2(int p, int n, BN_GENCB *cb) { @@ -38,11 +53,18 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb) */ rb_protect(rb_yield, ary, &state); if (state) { - arg->stop = 1; arg->state = state; + return 0; + } + } + if (arg->interrupted) { + arg->interrupted = 0; + state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL); + if (state) { + arg->state = state; + return 0; } } - if (arg->stop) return 0; return 1; } @@ -50,7 +72,7 @@ void ossl_generate_cb_stop(void *ptr) { struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr; - arg->stop = 1; + arg->interrupted = 1; } static void |