diff --git a/ext/digest/digest.c b/ext/digest/digest.c index a02eb12..1731ebe 100644 --- a/ext/digest/digest.c +++ b/ext/digest/digest.c @@ -624,6 +624,7 @@ rb_digest_base_update(VALUE self, VALUE str) TypedData_Get_Struct(self, void, &digest_type, pctx); StringValue(str); + str = rb_str_new_frozen(str); algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str)); RB_GC_GUARD(str); diff --git a/ext/digest/sha1/sha1.c b/ext/digest/sha1/sha1.c index 5311227..547834f 100644 --- a/ext/digest/sha1/sha1.c +++ b/ext/digest/sha1/sha1.c @@ -18,6 +18,7 @@ */ #include "sha1.h" +#include #define SHA1HANDSOFF /* Copies data before messing with it. */ @@ -218,7 +219,7 @@ int SHA1_Init(SHA1_CTX *context) /* * Run your data through this. */ -void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) +static void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) { uint32_t i, j; @@ -241,11 +242,36 @@ void SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len) (void)memcpy(&context->buffer[j], &data[i], len - i); } +struct unpack_nogvl { + SHA1_CTX *context; + const uint8_t *data; + size_t len; +}; + +void * SHA1_UpdateNoGVLUnpack(void * ptr) +{ + struct unpack_nogvl * args; + args = ptr; + SHA1_Update(args->context, args->data, args->len); + return NULL; +} + +void SHA1_UpdateNoGVL(SHA1_CTX *context, const uint8_t *data, size_t len) +{ + struct unpack_nogvl args; + args.context = context; + args.data = data; + args.len = len; + + rb_thread_call_without_gvl(SHA1_UpdateNoGVLUnpack, &args, NULL, NULL); + + return; +} /* * Add padding and return the message digest. */ -int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) +static int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) { size_t i; uint8_t finalcount[8]; @@ -269,3 +295,27 @@ int SHA1_Finish(SHA1_CTX* context, uint8_t digest[20]) } return 1; } + +struct finish_nogvl { + SHA1_CTX *context; + uint8_t *digest; +}; + +void * SHA1_FinishNoGVLUnpack(void * ptr) +{ + struct finish_nogvl * args; + args = ptr; + SHA1_Finish(args->context, args->digest); + return NULL; +} + +int SHA1_FinishNoGVL(SHA1_CTX* context, uint8_t digest[20]) +{ + struct finish_nogvl args; + args.context = context; + args.digest = digest; + + rb_thread_call_without_gvl(SHA1_FinishNoGVLUnpack, &args, NULL, NULL); + return 1; +} + diff --git a/ext/digest/sha1/sha1.h b/ext/digest/sha1/sha1.h index 6f1c388..4b24623 100644 --- a/ext/digest/sha1/sha1.h +++ b/ext/digest/sha1/sha1.h @@ -23,14 +23,12 @@ typedef struct { /* avoid name clash */ #define SHA1_Transform rb_Digest_SHA1_Transform #define SHA1_Init rb_Digest_SHA1_Init -#define SHA1_Update rb_Digest_SHA1_Update -#define SHA1_Finish rb_Digest_SHA1_Finish #endif void SHA1_Transform _((uint32_t state[5], const uint8_t buffer[64])); int SHA1_Init _((SHA1_CTX *context)); -void SHA1_Update _((SHA1_CTX *context, const uint8_t *data, size_t len)); -int SHA1_Finish _((SHA1_CTX *context, uint8_t digest[20])); +void SHA1_UpdateNoGVL _((SHA1_CTX *context, const uint8_t *data, size_t len)); +int SHA1_FinishNoGVL _((SHA1_CTX *context, uint8_t digest[20])); #define SHA1_BLOCK_LENGTH 64 #define SHA1_DIGEST_LENGTH 20 diff --git a/ext/digest/sha1/sha1init.c b/ext/digest/sha1/sha1init.c index 1f05808..cfef297 100644 --- a/ext/digest/sha1/sha1init.c +++ b/ext/digest/sha1/sha1init.c @@ -16,8 +16,8 @@ static const rb_digest_metadata_t sha1 = { SHA1_BLOCK_LENGTH, sizeof(SHA1_CTX), (rb_digest_hash_init_func_t)SHA1_Init, - (rb_digest_hash_update_func_t)SHA1_Update, - (rb_digest_hash_finish_func_t)SHA1_Finish, + (rb_digest_hash_update_func_t)SHA1_UpdateNoGVL, + (rb_digest_hash_finish_func_t)SHA1_FinishNoGVL, }; /*