Skip to content

Commit

Permalink
Revert "unlock the gvl when calculating hashes / salts"
Browse files Browse the repository at this point in the history
This reverts commit e1320b0.
  • Loading branch information
tenderlove committed Jul 21, 2020
1 parent a4528cf commit fbb89d7
Showing 1 changed file with 18 additions and 70 deletions.
88 changes: 18 additions & 70 deletions ext/mri/bcrypt_ext.c
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
#include <ruby.h>
#include <ow-crypt.h>

#ifdef HAVE_RUBY_THREAD_H
#include <ruby/thread.h>
#endif

static VALUE mBCrypt;
static VALUE cBCryptEngine;

struct bc_salt_args {
const char * prefix;
unsigned long count;
const char * input;
int size;
};

static void * bc_salt_nogvl(void * ptr) {
struct bc_salt_args * args = ptr;

return crypt_gensalt_ra(args->prefix, args->count, args->input, args->size);
}

/* Given a logarithmic cost parameter, generates a salt for use with +bc_crypt+.
*/
static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
char * salt;
VALUE str_salt;
struct bc_salt_args args;

/* duplicate the parameters for thread safety. If another thread has a
* reference to the parameters and mutates them while we are working,
* that would be very bad. Duping the strings means that the reference
* isn't shared. */
prefix = rb_str_new_frozen(prefix);
input = rb_str_new_frozen(input);

args.prefix = StringValueCStr(prefix);
args.count = NUM2ULONG(count);
args.input = NIL_P(input) ? NULL : StringValuePtr(input);
args.size = NIL_P(input) ? 0 : RSTRING_LEN(input);

#ifdef HAVE_RUBY_THREAD_H
salt = rb_thread_call_without_gvl(bc_salt_nogvl, &args, NULL, NULL);
#else
salt = bc_salt_nogvl((void *)&args);
#endif

salt = crypt_gensalt_ra(
StringValuePtr(prefix),
NUM2ULONG(count),
NIL_P(input) ? NULL : StringValuePtr(input),
NIL_P(input) ? 0 : RSTRING_LEN(input));

if(!salt) return Qnil;

Expand All @@ -54,52 +24,30 @@ static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
return str_salt;
}

struct bc_crypt_args {
const char * key;
const char * setting;
void * data;
int size;
};

static void * bc_crypt_nogvl(void * ptr) {
struct bc_crypt_args * args = ptr;

return crypt_ra(args->key, args->setting, &args->data, &args->size);
}

/* Given a secret and a salt, generates a salted hash (which you can then store safely).
*/
static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
char * value;
void * data;
int size;
VALUE out;

struct bc_crypt_args args;
data = NULL;
size = 0xDEADBEEF;

if(NIL_P(key) || NIL_P(setting)) return Qnil;

/* duplicate the parameters for thread safety. If another thread has a
* reference to the parameters and mutates them while we are working,
* that would be very bad. Duping the strings means that the reference
* isn't shared. */
key = rb_str_new_frozen(key);
setting = rb_str_new_frozen(setting);

args.data = NULL;
args.size = 0xDEADBEEF;
args.key = NIL_P(key) ? NULL : StringValueCStr(key);
args.setting = NIL_P(setting) ? NULL : StringValueCStr(setting);

#ifdef HAVE_RUBY_THREAD_H
value = rb_thread_call_without_gvl(bc_crypt_nogvl, &args, NULL, NULL);
#else
value = bc_crypt_nogvl((void *)&args);
#endif
value = crypt_ra(
NIL_P(key) ? NULL : StringValuePtr(key),
NIL_P(setting) ? NULL : StringValuePtr(setting),
&data,
&size);

if(!value || !args.data) return Qnil;
if(!value || !data) return Qnil;

out = rb_str_new(args.data, args.size - 1);
out = rb_str_new2(value);

free(args.data);
xfree(data);

return out;
}
Expand Down

0 comments on commit fbb89d7

Please sign in to comment.