Sorry I wasn't too clear in my initial message.

The problem is that, because the component is designed to handle
multiple requests in parallel, I set an alarm for each request,
and then, when there is an I/O activity, I need to remove the
alarm set for the particular request where the I/O activity has
happened and add a new alarm, and when a request completes,
remove the alarm set for that particular request.

So there could be a number of solutions:

(a) Create a new session for each incoming request. Hope not.

(b) Whenever an alarm needs to be removed, remove all alarms
and requeue all of them except that one. queue_peek_alarms is
not of use here, because it returns event names only, which
are all the same, but even if it was it would still be ugly
as hell. Basically this solution implies my keeping an array
of pending alarms and requeuing them all whenever any activity
happens on any of the pending requests.

(c) Have a way to remove a single pending alarm. For that some
kind of alarm ID would be needed, along with an alarm_remove
kernel method that would take an alarm ID. The code I posted
in a previous message appears to work, except occasionally it
complains about an uninitialized value in the != comparison,
which right now I have no idea why it happens.

# code goes to Kernel.pm

# to be called by client right after adding an alarm
sub last_seqnum
{
    return $queue_seqnum;
}

# pass an alarm's seqnum to kill it
sub alarm_remove
{
    my $seqnum = shift;
    $seqnum = shift if ref $seqnum;
    my $index = 0;
    $index ++ while $index < @kr_alarms and $kr_alarms[$index]->[ST_SEQ] != $seqnum;
    return unless $index < @kr_alarms;
    {% ses_refcount_dec2 $kr_alarms[$index]->[ST_SESSION], SS_ALCOUNT %}
    splice @kr_alarms, $index, 1;
    warn "Alarm #$seqnum removed\n" if TRACE_EVENTS;
}

Kirill

PS - I'm subscribed to the POE list, so there's no need to CC me.


> From: "Rocco Caputo" <[EMAIL PROTECTED]>
> Sent: Thursday, May 24, 2001 11:01 PM
> Subject: Re: select() as sleep()
>
> If I read the messages correctly, you need to keep refreshing a timer
> whenever activity occurs.  POE::Kernel's alarm() and delay() methods
> do this: they clear existing timed events for the given state before
> setting new ones.
> 
> So every time you call this:
> 
>   $kernel->delay( timeout => 5 );
> 
> The previous 'timeout' delay is cleared and a new one is set for five
> seconds into the future.  To clear the delay it without setting a new
> one, you would call this:
> 
>   $kernel->delay( 'timeout' );
> 
> Since delay() clears the previous one (if any), it removes the old
> 'timeout' delay.  Since there is no time for a new 'timeout', no new
> one is set.
> 
> This may not help if I misunderstood your previous message.

Reply via email to