Project

General

Profile

Bug #13935 » ruby_2_3-0004-ossl.c-use-struct-CRYPTO_dynlock_value-for-non-dynam.patch

rhenium (Kazuki Yamaguchi), 09/24/2017 04:48 PM

View differences:

ext/openssl/ossl.c
* Stores locks needed for OpenSSL thread safety
*/
#include "ruby/thread_native.h"
static rb_nativethread_lock_t *ossl_locks;
struct CRYPTO_dynlock_value {
rb_nativethread_lock_t lock;
};
static void
ossl_lock_unlock(int mode, rb_nativethread_lock_t *lock)
ossl_lock_init(struct CRYPTO_dynlock_value *l)
{
if (mode & CRYPTO_LOCK) {
rb_nativethread_lock_lock(lock);
} else {
rb_nativethread_lock_unlock(lock);
}
rb_nativethread_lock_initialize(&l->lock);
}
static void
ossl_lock_callback(int mode, int type, const char *file, int line)
ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
{
ossl_lock_unlock(mode, &ossl_locks[type]);
if (mode & CRYPTO_LOCK) {
rb_nativethread_lock_lock(&l->lock);
} else {
rb_nativethread_lock_unlock(&l->lock);
}
}
struct CRYPTO_dynlock_value {
rb_nativethread_lock_t lock;
};
static struct CRYPTO_dynlock_value *
ossl_dyn_create_callback(const char *file, int line)
{
struct CRYPTO_dynlock_value *dynlock = (struct CRYPTO_dynlock_value *)OPENSSL_malloc((int)sizeof(struct CRYPTO_dynlock_value));
rb_nativethread_lock_initialize(&dynlock->lock);
/* Do not use xmalloc() here, since it may raise NoMemoryError */
struct CRYPTO_dynlock_value *dynlock =
OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value));
if (dynlock)
ossl_lock_init(dynlock);
return dynlock;
}
static void
ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
{
ossl_lock_unlock(mode, &l->lock);
ossl_lock_unlock(mode, l);
}
static void
......
}
#endif
static struct CRYPTO_dynlock_value *ossl_locks;
static void
ossl_lock_callback(int mode, int type, const char *file, int line)
{
ossl_lock_unlock(mode, &ossl_locks[type]);
}
static void Init_ossl_locks(void)
{
int i;
int num_locks = CRYPTO_num_locks();
if ((unsigned)num_locks >= INT_MAX / (int)sizeof(VALUE)) {
rb_raise(rb_eRuntimeError, "CRYPTO_num_locks() is too big: %d", num_locks);
}
ossl_locks = (rb_nativethread_lock_t *) OPENSSL_malloc(num_locks * (int)sizeof(rb_nativethread_lock_t));
if (!ossl_locks) {
rb_raise(rb_eNoMemError, "CRYPTO_num_locks() is too big: %d", num_locks);
}
for (i = 0; i < num_locks; i++) {
rb_nativethread_lock_initialize(&ossl_locks[i]);
}
ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks);
for (i = 0; i < num_locks; i++)
ossl_lock_init(&ossl_locks[i]);
#ifdef HAVE_CRYPTO_THREADID_PTR
CRYPTO_THREADID_set_callback(ossl_threadid_func);
(5-5/8)