sergot / openssl

OpenSSL bindings for Perl 6
MIT License
14 stars 31 forks source link

Thread safety #31

Open chrsteel opened 8 years ago

chrsteel commented 8 years ago

The following code fails for me and gives the cryptic error message "Cannot unbox a type object":

#!/usr/bin/perl6
use v6;
use OpenSSL;

sub new-socket {
    my $socket = IO::Socket::INET.new( :host<github.com> :port(443) );
    my $ssl = OpenSSL.new(:client);
    $ssl.set-socket($socket);
    $ssl.set-connect-state;
    $ssl.connect;
}

my $p1 = start { new-socket };
my $p2 = start { new-socket };

await $p1;
await $p2;

Note that there is no error if the lines containing $p2 are removed.

The basic Socket:INET seems already to be thread safe. Is there hope for thread safe SSL-sockets?

vadz commented 7 years ago

According to OpenSSL documentation, we need to set locking functions to use it from multiple threads and currently this is not done.

I'm not sure how is it going to be possible to define C callbacks working with mutexes from Perl6 code...

FWIW #34 contains another example showing that using this module from multiple threads currently doesn't work.

ugexe commented 7 years ago

FYI IO::Socket::INET is only thread safe if you read a socket in the thread it was created

chrsteel commented 7 years ago

It's a pity that going from IO::Socket::Async to something like IO::Socket::Async:SSL seems so hard.

And yes, I was already aware of the limitation that each socket can only be used in one thread.

Thank you for the info though! (I now worked around the problem by serializing all SSL-requests in my application.)

ugexe commented 7 years ago

You can write a naive SSL Async wrapper in ~50 LoC https://gist.github.com/ugexe/71d82eb4bb5653125bd8

chrsteel commented 7 years ago

That's great, this should be a module! Hmm.. but its still not thread safe, I presume? If I cannot do concurrent requests, I might probably just as well use IO::Socket::SSL. :-/

ugexe commented 7 years ago

I'm not sure if it's thread safe. All the data is fetched with IO::Socket::Async so that data should be able to cross threads unlike INET. But I'm not sure how/if that changes what happens with OpenSSL accessing that data - it was too slow for what I needed so I didn't test it further

jnthn commented 7 years ago

There is now an IO::Socket::Async::SSL, which can work across multiple threads (tests for that included in its test suite).

chrsteel commented 7 years ago

Awesome!! Thank you jnthn!