Skip to content

Instantly share code, notes, and snippets.

@Watson1978
Created April 9, 2011 04:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Watson1978/911139 to your computer and use it in GitHub Desktop.
Save Watson1978/911139 to your computer and use it in GitHub Desktop.
# Multiple, concurrent SSL requests
#
# works in Ruby 1.9.2, but Segfaults in Macruby 0.10
require 'net/http';require "net/https"
def do_https
http=Net::HTTP.new('www.paypal.com', 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.start() {|http|
req = Net::HTTP::Get.new('/')
response = http.request(req)
puts "done, got #{response.body.size} bytes"
}
end
t = []
40.times do
t << Thread.new {do_https}
end
t.each do |th|
th.join
end
puts "done with all threads"
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index c344333..66f3a11 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -129,6 +129,8 @@ int ossl_ssl_ex_ptr_idx;
int ossl_ssl_ex_client_cert_cb_idx;
int ossl_ssl_ex_tmp_dh_callback_idx;
+static pthread_mutex_t *ossl_mutex = NULL;
+
static void
ossl_sslctx_free(SSL_CTX *ctx)
{
@@ -1545,6 +1547,50 @@ ossl_ssl_get_verify_result(VALUE self)
return INT2FIX(SSL_get_verify_result(ssl));
}
+static void
+ossl_lock_callback(int mode, int n, const char *file, int line)
+{
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&ossl_mutex[n]);
+ }
+ else {
+ pthread_mutex_unlock(&ossl_mutex[n]);
+ }
+}
+
+static unsigned long
+ossl_id_callback(void)
+{
+ return (unsigned long)pthread_self();
+}
+
+static void
+ossl_lock_init(void)
+{
+ int i;
+
+ ossl_mutex = (pthread_mutex_t*)malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+ for(i = 0; i < CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&ossl_mutex[i], NULL);
+ }
+ CRYPTO_set_locking_callback(ossl_lock_callback);
+ CRYPTO_set_id_callback(ossl_id_callback);
+}
+
+// TODO: call this finalizer when MacRuby is finished.
+static void
+ossl_lock_finalize(void)
+{
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ CRYPTO_set_id_callback(NULL);
+ for(i = 0; i < CRYPTO_num_locks(); i++) {
+ pthread_mutex_destroy(&ossl_mutex[i]);
+ }
+ free(ossl_mutex);
+}
+
void
Init_ossl_ssl()
{
@@ -1690,4 +1736,6 @@ Init_ossl_ssl()
ossl_ssl_def_const(OP_PKCS1_CHECK_2);
ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+
+ ossl_lock_init();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment