1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Test::Refcount;
use Future;
use Future::Utils qw( call_with_escape );
# call_with_escape normal return
{
my $ret_f;
my $f = call_with_escape {
return $ret_f = Future->new;
};
$ret_f->done( "result" );
ok( $f->is_ready, 'call_with_escape ready after returned future ready' );
is( scalar $f->get, "result", 'result of call_with_escape' );
$f = call_with_escape {
return $ret_f = Future->new;
};
$ret_f->fail( "failure" );
ok( $f->is_ready, 'call_with_escape ready after returned future ready' );
is( scalar $f->failure, "failure", 'result of call_with_escape' );
undef $ret_f;
is_oneref( $f, 'call_with_escape has refcount 1 before EOF' );
}
# call_with_escape synchronous escape
{
my $f = call_with_escape {
my $escape = shift;
$escape->done( "escaped" );
};
ok( $f->is_ready, 'call_with_escape ready after synchronous escape' );
is( scalar $f->get, "escaped", 'result of call_with_escape' );
}
# call_with_escape delayed escape
{
my $ret_f = Future->new;
my $inner_f;
my $f = call_with_escape {
my $escape = shift;
return $inner_f = $ret_f->then( sub {
return $escape->done( "later escape" );
});
};
ok( !$f->is_ready, 'call_with_escape not yet ready before deferral' );
$ret_f->done;
ok( $f->is_ready, 'call_with_escape ready after deferral' );
is( scalar $f->get, "later escape", 'result of call_with_escape' );
ok( $inner_f->is_cancelled, 'code-returned future cancelled after escape' );
}
done_testing;
|