Skip to content

Commit 8bb519b

Browse files
committed
pkey: resume key generation after interrupt
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
1 parent 1f90516 commit 8bb519b

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

ext/openssl/ossl_pkey.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ static ID id_private_q;
2020
/*
2121
* callback for generating keys
2222
*/
23+
static VALUE
24+
call_check_ints0(VALUE arg)
25+
{
26+
rb_thread_check_ints();
27+
return Qnil;
28+
}
29+
30+
static void *
31+
call_check_ints(void *arg)
32+
{
33+
int state;
34+
rb_protect(call_check_ints0, Qnil, &state);
35+
return (void *)(VALUE)state;
36+
}
37+
2338
int
2439
ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
2540
{
@@ -38,19 +53,26 @@ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
3853
*/
3954
rb_protect(rb_yield, ary, &state);
4055
if (state) {
41-
arg->stop = 1;
4256
arg->state = state;
57+
return 0;
58+
}
59+
}
60+
if (arg->interrupted) {
61+
arg->interrupted = 0;
62+
state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL);
63+
if (state) {
64+
arg->state = state;
65+
return 0;
4366
}
4467
}
45-
if (arg->stop) return 0;
4668
return 1;
4769
}
4870

4971
void
5072
ossl_generate_cb_stop(void *ptr)
5173
{
5274
struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
53-
arg->stop = 1;
75+
arg->interrupted = 1;
5476
}
5577

5678
static void

ext/openssl/ossl_pkey.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extern const rb_data_type_t ossl_evp_pkey_type;
4141

4242
struct ossl_generate_cb_arg {
4343
int yield;
44-
int stop;
44+
int interrupted;
4545
int state;
4646
};
4747
int ossl_generate_cb_2(int p, int n, BN_GENCB *cb);

0 commit comments

Comments
 (0)