Skip to content

Commit 45e8dc1

Browse files
authored
Fix OpenSSL <1.1.0 threads setup. (#111)
* Fix OpenSSL <1.1.0 threads setup. OpenSSL 1.0.2 and older require expicit locking callbacks in order to be thread safe. Without this fix, using TLS and multiple threads on older versions of OpenSSL would result with crashes/unexpected behavior.
1 parent 1f93bc1 commit 45e8dc1

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

memtier_benchmark.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,55 @@ run_stats run_benchmark(int run_id, benchmark_config* cfg, object_generator* obj
11381138
}
11391139

11401140
#ifdef USE_TLS
1141+
1142+
#pragma GCC diagnostic push
1143+
#pragma GCC diagnostic ignored "-Wunused-function"
1144+
static pthread_mutex_t *__openssl_locks;
1145+
1146+
static void __openssl_locking_callback(int mode, int type, const char *file, int line)
1147+
{
1148+
if (mode & CRYPTO_LOCK) {
1149+
pthread_mutex_lock(&(__openssl_locks[type]));
1150+
} else {
1151+
pthread_mutex_unlock(&(__openssl_locks[type]));
1152+
}
1153+
}
1154+
1155+
static unsigned long __openssl_thread_id(void)
1156+
{
1157+
unsigned long id;
1158+
1159+
id = (unsigned long) pthread_self();
1160+
return id;
1161+
}
1162+
#pragma GCC diagnostic pop
1163+
1164+
static void init_openssl_threads(void)
1165+
{
1166+
int i;
1167+
1168+
__openssl_locks = (pthread_mutex_t *) malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
1169+
assert(__openssl_locks != NULL);
1170+
1171+
for (i = 0; i < CRYPTO_num_locks(); i++) {
1172+
pthread_mutex_init(&(__openssl_locks[i]), NULL);
1173+
}
1174+
1175+
CRYPTO_set_id_callback(__openssl_thread_id);
1176+
CRYPTO_set_locking_callback(__openssl_locking_callback);
1177+
}
1178+
1179+
static void cleanup_openssl_threads(void)
1180+
{
1181+
int i;
1182+
1183+
CRYPTO_set_locking_callback(NULL);
1184+
for (i = 0; i < CRYPTO_num_locks(); i++) {
1185+
pthread_mutex_destroy(&(__openssl_locks[i]));
1186+
}
1187+
OPENSSL_free(__openssl_locks);
1188+
}
1189+
11411190
static void init_openssl(void)
11421191
{
11431192
SSL_library_init();
@@ -1146,7 +1195,15 @@ static void init_openssl(void)
11461195
fprintf(stderr, "Failed to initialize OpenSSL random entropy.\n");
11471196
exit(1);
11481197
}
1198+
1199+
init_openssl_threads();
11491200
}
1201+
1202+
static void cleanup_openssl(void)
1203+
{
1204+
cleanup_openssl_threads();
1205+
}
1206+
11501207
#endif
11511208

11521209
int main(int argc, char *argv[])
@@ -1526,5 +1583,7 @@ int main(int argc, char *argv[])
15261583
SSL_CTX_free(cfg.openssl_ctx);
15271584
cfg.openssl_ctx = NULL;
15281585
}
1586+
1587+
cleanup_openssl();
15291588
#endif
15301589
}

0 commit comments

Comments
 (0)