AnyEvent-SIP

 view release on metacpan or  search on metacpan

lib/Net/SIP/Dispatcher/AnyEvent.pm  view on Meta::CPAN

use warnings;
package Net::SIP::Dispatcher::AnyEvent;
{
  $Net::SIP::Dispatcher::AnyEvent::VERSION = '0.002';
}
# ABSTRACT: AnyEvent dispatcher for Net::SIP

use AnyEvent;
use Net::SIP::Dispatcher::AnyEvent::Timer;
use Net::SIP::Util 'invoke_callback';
use AnyEvent::AggressiveIdle ();

sub new {
    my $class = shift;
    my %args  = @_;
    my $self  = bless {
        _cv          => AE::cv,
        _ae_interval => $args{'_ae_interval'} || 0.2,
    }, $class;

    if ( $args{'_net_sip_compat'} ) {
        $self->{'_idle'} = AnyEvent::AggressiveIdle::aggressive_idle {
            exists $self->{'_stopvar'} or return;
            foreach my $var ( @{ $self->{'_stopvar'} } ) {
                if ( ${$var} ) {
                    delete $self->{'_stopvar'};
                    $self->{'_cv'}->send;
                }
            }
        };
    }

    return $self;
}

sub addFD {
    my $self = shift;
    my ( $fh, $cb_data, $name ) = @_;

    my $fn = fileno $fh or return;

    $self->{'_fd_watchers'}{$fn} = AE::io $fh, 0, sub {
        invoke_callback( $cb_data, $fh );
    }
}

sub delFD {
    my $self = shift;
    my $fh   = shift;
    my $fn   = fileno $fh or return;

    delete $self->{'_fd_watchers'}{$fn};
}

sub add_timer {
    my $self = shift;
    my ( $when, $cb_data, $repeat, $name ) = @_;
    defined $repeat or $repeat = 0;

    # is $when epoch or relative?
    if ( $when >= 3600*24*365 ) {
        $when = AE::now - $when;
    }

    return Net::SIP::Dispatcher::AnyEvent::Timer->new(
        $name, $when, $repeat, $cb_data
    );
}

sub looptime { AE::now }

sub loop {
    my $self = shift;
    my ( $timeout, @stopvar ) = @_;

    $self->{'_stopvar'} = \@stopvar;

    if ( ! $self->{'_net_sip_compat'} and @stopvar ) {
        # set up a timer to check stopvars
        $self->{'_stopvar_timer'} = AE::timer 0, $self->{'_ae_interval'}, sub {
            foreach my $var (@stopvar) {
                if ( ${$var} ) {
                    delete $self->{'_stopvar_timer'};
                    delete $self->{'_stopvar'};
                    $self->{'_cv'}->send;
                }
            }
        }
    }

    if ($timeout) {
        my $timer; $timer = AE::timer $timeout, 0, sub {
            undef $timer;
            $self->{'_cv'}->send;
        };
    }

    $self->{'_cv'}->recv;

    # clean up, prepare for another round
    $self->{'_cv'} = AE::cv;
}

1;



=pod

=head1 NAME

Net::SIP::Dispatcher::AnyEvent - AnyEvent dispatcher for Net::SIP

=head1 VERSION

version 0.002

=head1 DESCRIPTION

This module allows L<Net::SIP> to work with L<AnyEvent> as the event loop,
instead of its own. This means you can combine them.



( run in 1.182 second using v1.01-cache-2.11-cpan-39bf76dae61 )