Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[perl #40827] [BUG] testing alarm with exception handlers causes runloops to play leapfrog

9 views
Skip to first unread message

Jerry Gay

unread,
Nov 11, 2006, 10:15:52 PM11/11/06
to bugs-bi...@rt.perl.org
# New Ticket Created by Jerry Gay
# Please include the string: [perl #40827]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=40827 >


the code below is broken while testing alarm with exception handlers.
i wish i could debug it, but it hurts my brain. maybe somebody smart
(bob?) about exception handlers can have a look and tell me what's
what.
~jerry

OUTPUT:
>parrot t-alarm.pir
1..3
[oops; continuation 005B6B08 of type 25 is trying to jump from runloop 10 to run
loop 1]
ok 1
not ok 2
1
current instr.: 'alarm_handler' pc 128 (t-alarm.pir:69)
called from Sub 'alarm_is' pc 78 (t-alarm.pir:40)
called from Sub 'main' pc 53 (t-alarm.pir:16)

>


CODE:
#!./parrot

## load the dynamic opcode library that contains 'alarm'
.loadlib 'myops_ops'

.sub 'main' :main
load_bytecode 'Test/More.pir'

.local pmc plan
plan = get_global ['Test::More'], 'plan'

plan(3)

'alarm_is'( 3.0, 3.0, 1, 1, 'alarm: set: 3.0; check: 3.0; true' )
'alarm_is'( 3.0, 4.0, 1, 2, 'alarm: set: 3.0; check: 4.0; true' )
'alarm_is'( 3.0, 2.0, 0, 3, 'alarm: set: 3.0; check: 2.0; false' )
.end


.sub 'alarm_is'
.param num set ## this value is used to set the alarm
.param num check ## this is how long the test waits
.param int expected
.param int testnum
.param string desc :optional
.param int has_desc :opt_flag

.local pmc is
is = get_global ['Test::More'], 'is'

.local num time_start
time_start = time

.local num time_check
.local int result

.const .Sub alarm_handler = 'alarm_handler'
alarm set, alarm_handler

push_eh test

loop:
time_check = time
time_check -= time_start
if time_check >= set goto end_loop
sleep 1
goto loop
end_loop:
$P0 = new .Exception
$P0[0] = 0
throw $P0

test:
.local pmc exception
.local int result
get_results '0,0', exception, result
eq result, expected, ok
nok:
print 'not '
ok:
print 'ok '
print testnum
print "\n"
.end

.sub 'alarm_handler'
$P0 = new .Exception
$P0[0] = 1
throw $P0
.end

Bob Rogers

unread,
Nov 11, 2006, 11:06:19 PM11/11/06
to perl6-i...@perl.org, bugs-bi...@rt.perl.org
From: Jerry Gay (via RT) <parrotbug...@parrotcode.org>
Date: Sat, 11 Nov 2006 19:15:52 -0800

the code below is broken while testing alarm with exception handlers.
i wish i could debug it, but it hurts my brain. maybe somebody smart
(bob?) about exception handlers can have a look and tell me what's
what.

~jerry

Thanks for the plug, but this is my first look at events, where I'm
definitely *not* smart. However, I do see that do_event in src/events.c
is indeed calling an inferior runloop to run the event sub. And that
means that throwing an exception from the alarm sub just won't work.

But should we expect it work? In general, timer code can't assume
that the right handler will get control. You may have bound a handler
that you expect will catch the error, but what if some other module you
are using happens to bind an overly-general handler at just the wrong
moment? It just doesn't seem robust.

Of course, this doesn't really apply to your test script. And
exceptions in timer events really ought to work in any case. But the
right way to fix it involves turning a nontrivial amount of src/events.c
code inside out, and I don't yet have a good way to do that. Thanks for
pointing this out, though; I will factor this case into my thinking on
this problem.

-- Bob Rogers
http://rgrjr.dyndns.org/

P.S. For the record, it would not be hard to teach Continuation:invoke
to cross runloop barriers for exception handling (among others), since
such continuations can only go down the stack. But I've been resisting
the temptation, since we'd still need to do the same code rewriting to
support upward continuations, including coroutines. Inferior runloops
are evil.

0 new messages