Skip to content

Commit

Permalink
Merge branch 'master' into the-d
Browse files Browse the repository at this point in the history
  • Loading branch information
zoffixznet committed Oct 27, 2018
2 parents 46ef0ea + 933f936 commit 7dc152e
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 115 deletions.
18 changes: 1 addition & 17 deletions src/Perl6/Actions.nqp
Expand Up @@ -325,21 +325,6 @@ sub unwanted($ast, $by) {
$ast.sunk(1);
}
elsif $ast.op eq 'callmethod' {
if $ast.has_ann('promise_starter') && ! $*W.lang-ver-before('d') {
$ast[1] := QAST::WVal.new: value =>
$*W.find_symbol(['&trait_mod:<is>'])(:hidden-from-backtrace,
$*W.create_thunk: $ast.node,
QAST::Op.new: :op<handle>,
QAST::Op.new(:op<call>, $ast[1]), # Promised code block
'CATCH',
QAST::Op.new: :op<callmethod>,
:name<handle-exception>,
QAST::Op.new(:op<getcomp>,
QAST::SVal.new: :value<perl6>),
QAST::Op.new: :op<exception>
);
return $ast;
}
if !$ast.nosink && !$*COMPILING_CORE_SETTING && !%nosink{$ast.name} {
return $ast if $*ALREADY_ADDED_SINK_CALL;
$ast.sunk(1);
Expand Down Expand Up @@ -2755,13 +2740,12 @@ class Perl6::Actions is HLL::Actions does STDActions {
$*W.install_lexical_magical($block, '$!');
}
make QAST::Op.new(
:node($/),
:op('callmethod'),
:name('start'),
:returns($*W.find_symbol(['Promise'])),
QAST::WVal.new( :value($*W.find_symbol(['Promise'])) ),
$<blorst>.ast
).annotate_self: 'promise_starter', 1;
);
}

method statement_prefix:sym<lazy>($/) {
Expand Down
137 changes: 53 additions & 84 deletions src/core/IO/Socket/Async.pm6
Expand Up @@ -123,7 +123,6 @@ my class IO::Socket::Async {
$tap := Tap.new({ nqp::cancel($cancellation) });
tap($tap);
}

$!close-promise.then: {
$lock.protect: {
unless $finished {
Expand Down Expand Up @@ -166,65 +165,42 @@ my class IO::Socket::Async {
$!close-vow.keep(True);
}

sub create-socket(Bool :$listening = False, :$scheduler = $*SCHEDULER, Bool :$hint-affinity = False --> Promise) {
my Promise $p .= new;
my $v = $p.vow;
nqp::asyncsocket(
$scheduler.queue(:$hint-affinity),
-> Mu \socket, Mu \err {
if err {
$v.break: err;
} else {
$v.keep: socket;
}
},
nqp::unbox_i($listening ?? 1 !! 0),
SocketCancellation
);
$p;
}

method connect(IO::Socket::Async:U: Str() $host, Int() $port,
:$enc = 'utf-8', :$scheduler = $*SCHEDULER) {
my Promise $p .= new;
my $p = Promise.new;
my $v = $p.vow;
my \server-socket = create-socket(:$scheduler).result;
my $encoding = Encoding::Registry.find($enc);
nqp::asyncconnect(
$scheduler.queue,
-> Mu \client-socket, Mu \err, Mu \peer-host, Mu \peer-port, Mu \socket-host, Mu \socket-port {
-> Mu \socket, Mu \err, Mu \peer-host, Mu \peer-port, Mu \socket-host, Mu \socket-port {
if err {
$v.break: err;
} else {
my \client = nqp::create(self);
my $encoding = Encoding::Registry.find($enc);
nqp::bindattr(client, IO::Socket::Async, '$!VMIO', client-socket);
nqp::bindattr(client, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr(client, IO::Socket::Async, '$!encoder', $encoding.encoder());
nqp::bindattr(client, IO::Socket::Async, '$!peer-host', peer-host);
nqp::bindattr(client, IO::Socket::Async, '$!peer-port', peer-port);
nqp::bindattr(client, IO::Socket::Async, '$!socket-host', socket-host);
nqp::bindattr(client, IO::Socket::Async, '$!socket-port', socket-port);
setup-close(client);
$v.keep: client;
$v.break(err);
}
else {
my $client_socket := nqp::create(self);
nqp::bindattr($client_socket, IO::Socket::Async, '$!VMIO', socket);
nqp::bindattr($client_socket, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr($client_socket, IO::Socket::Async, '$!encoder',
$encoding.encoder());
nqp::bindattr($client_socket, IO::Socket::Async, '$!peer-host', peer-host);
nqp::bindattr($client_socket, IO::Socket::Async, '$!peer-port', peer-port);
nqp::bindattr($client_socket, IO::Socket::Async, '$!socket-host', socket-host);
nqp::bindattr($client_socket, IO::Socket::Async, '$!socket-port', socket-port);

setup-close($client_socket);
$v.keep($client_socket);
}
},
server-socket, $host, $port, SocketCancellation);
$host, $port, SocketCancellation);
$p
}

class ListenSocket is Tap {
has $!VMIO;
has Promise $.socket-host;
has Promise $.socket-port;

submethod BUILD(Mu :$!VMIO, Promise :$!socket-host, Promise :$!socket-port) { }

method new(&on-close!, Mu :$VMIO!, Promise :$socket-host!, Promise :$socket-port!) {
self.bless: :&on-close, :$VMIO, :$socket-host, :$socket-port;
}

method native-descriptor(--> Int) {
nqp::filenofh(nqp::decont($!VMIO))
method new(&on-close, Promise :$socket-host, Promise :$socket-port) {
self.bless(:&on-close, :$socket-host, :$socket-port);
}
}

Expand All @@ -241,10 +217,9 @@ my class IO::Socket::Async {

method !SET-SELF($!host, $!port, $!backlog, $!encoding, $!scheduler) { self }

method tap(&emit, &done, &quit, &tap --> ListenSocket) {
method tap(&emit, &done, &quit, &tap) {
my $lock := Lock::Async.new;
my $tap;
my $VMIO = create-socket(:listening, :$!scheduler, :hint-affinity).result;
my int $finished = 0;
my Promise $socket-host .= new;
my Promise $socket-port .= new;
Expand All @@ -267,43 +242,42 @@ my class IO::Socket::Async {
$finished = 1;
}
elsif socket {
my \client := nqp::create(IO::Socket::Async);
nqp::bindattr(client, IO::Socket::Async,
my $client_socket := nqp::create(IO::Socket::Async);
nqp::bindattr($client_socket, IO::Socket::Async,
'$!VMIO', socket);
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!enc', $!encoding.name);
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!encoder', $!encoding.encoder());
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!peer-host', peer-host);
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!peer-port', peer-port);
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!socket-host', socket-host);
nqp::bindattr(client, IO::Socket::Async,
nqp::bindattr($client_socket, IO::Socket::Async,
'$!socket-port', socket-port);
setup-close(client);
emit(client);
setup-close($client_socket);
emit($client_socket);
}
elsif socket-host {
$host-vow.keep(~socket-host);
$port-vow.keep(+socket-port);
}
}
},
nqp::decont($VMIO), $!host, $!port, $!backlog, SocketCancellation);
$!host, $!port, $!backlog, SocketCancellation);
$tap = ListenSocket.new: {
my $p = Promise.new;
my $v = $p.vow;
nqp::cancelnotify($cancellation, $!scheduler.queue, { $v.keep(True); });
$p
}, :$VMIO, :$socket-host, :$socket-port;
}, :$socket-host, :$socket-port;
tap($tap);

CATCH {
default {
tap($tap = ListenSocket.new: { Nil }, :$VMIO,
:$socket-host, :$socket-port) unless $tap;
tap($tap = ListenSocket.new({ Nil },
:$socket-host, :$socket-port)) unless $tap;
quit($_);
}
}
Expand All @@ -318,10 +292,9 @@ my class IO::Socket::Async {

method listen(IO::Socket::Async:U: Str() $host, Int() $port, Int() $backlog = 128,
:$enc = 'utf-8', :$scheduler = $*SCHEDULER) {
my $encoding = Encoding::Registry.find: $enc;
my $tappable = SocketListenerTappable.new:
:$host, :$port, :$backlog, :$encoding, :$scheduler;
Supply.new: $tappable;
my $encoding = Encoding::Registry.find($enc);
Supply.new: SocketListenerTappable.new:
:$host, :$port, :$backlog, :$encoding, :$scheduler
}

sub setup-close(\socket --> Nil) {
Expand All @@ -330,10 +303,6 @@ my class IO::Socket::Async {
nqp::bindattr(socket, IO::Socket::Async, '$!close-vow', $p.vow);
}

method native-descriptor(--> Int) {
nqp::filenofh(nqp::decont($!VMIO))
}

#?if moar
method udp(IO::Socket::Async:U: :$broadcast, :$enc = 'utf-8', :$scheduler = $*SCHEDULER) {
my $p = Promise.new;
Expand All @@ -345,14 +314,14 @@ my class IO::Socket::Async {
$p.break(err);
}
else {
my \client := nqp::create(self);
nqp::bindattr(client, IO::Socket::Async, '$!VMIO', socket);
nqp::bindattr_i(client, IO::Socket::Async, '$!udp', 1);
nqp::bindattr(client, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr(client, IO::Socket::Async, '$!encoder',
my $client_socket := nqp::create(self);
nqp::bindattr($client_socket, IO::Socket::Async, '$!VMIO', socket);
nqp::bindattr_i($client_socket, IO::Socket::Async, '$!udp', 1);
nqp::bindattr($client_socket, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr($client_socket, IO::Socket::Async, '$!encoder',
$encoding.encoder());
setup-close(client);
$p.keep(client);
setup-close($client_socket);
$p.keep($client_socket);
}
},
nqp::null_s(), 0, $broadcast ?? 1 !! 0,
Expand All @@ -371,14 +340,14 @@ my class IO::Socket::Async {
$p.break(err);
}
else {
my \client := nqp::create(self);
nqp::bindattr(client, IO::Socket::Async, '$!VMIO', socket);
nqp::bindattr_i(client, IO::Socket::Async, '$!udp', 1);
nqp::bindattr(client, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr(client, IO::Socket::Async, '$!encoder',
my $client_socket := nqp::create(self);
nqp::bindattr($client_socket, IO::Socket::Async, '$!VMIO', socket);
nqp::bindattr_i($client_socket, IO::Socket::Async, '$!udp', 1);
nqp::bindattr($client_socket, IO::Socket::Async, '$!enc', $encoding.name);
nqp::bindattr($client_socket, IO::Socket::Async, '$!encoder',
$encoding.encoder());
setup-close(client);
$p.keep(client);
setup-close($client_socket);
$p.keep($client_socket);
}
},
nqp::unbox_s($host), nqp::unbox_i($port), $broadcast ?? 1 !! 0,
Expand Down
6 changes: 0 additions & 6 deletions src/core/traits.pm6
Expand Up @@ -374,12 +374,6 @@ multi sub trait_mod:<of>(Routine:D $target, Mu:U $type) {
$target.^mixin(Callable.^parameterize($type))
}

multi sub trait_mod:<is>(Code:D $r, :$hidden-from-backtrace!) {
$r.^mixin( role is-hidden-from-backtrace {
method is-hidden-from-backtrace(--> True) { }
}) if $hidden-from-backtrace;
}

multi sub trait_mod:<is>(Routine:D $r, :$hidden-from-backtrace!) {
$r.^mixin( role is-hidden-from-backtrace {
method is-hidden-from-backtrace(--> True) { }
Expand Down
17 changes: 9 additions & 8 deletions t/05-messages/02-errors.t
Expand Up @@ -16,14 +16,15 @@ throws-like { for [:a] X [:b] -> ($i, $j) { } },
message => / '<anon>' /,
"anonymous subs get '<anon>' in arity error messages";

if $*DISTRO.is-win {
skip 'test appears to hang on Windows (long socket timeouts?); https://github.com/rakudo/rakudo/issues/2424';
}
else {
throws-like {
react whenever IO::Socket::Async.listen: "localhost", 2¹⁶+100 {}
}, X::AdHoc, message => 'invalid argument';
}
todo 'needs better error message';

skip 'crashes: https://github.com/rakudo/rakudo/issues/2402';
#throws-like {
# sub l { IO::Socket::Async.listen: "localhost", 111390 }
# react whenever l() {
# whenever l() {} # try to listen on already open sock
# }
#}, X::AdHoc, message => /'something good'/;

# RT #132283
is-deeply class { has $.bar }.^methods».name.sort, <BUILDALL bar>,
Expand Down

0 comments on commit 7dc152e

Please sign in to comment.