Laotsu has asked for the wisdom of the Perl Monks concerning the following question:

In the following code, if I comment out the calls to InitAsterisk and DoneAsterisk, MainLoop exits as expected. however, if I leave the calls in place, MainLoop never exits. ("1" is never printed, and a ctrl-C is needed to get a prompt back.

Normally, I would put the Init first, and the Done in the Exit sub, but I did this to show that simply calling InitAsterisk causes the problem. Even if the data is wrong and no connection is made to the AMI, the behavior is the same.

What have I done wrong? (karma aside)
use Tk; use Asterisk::AMI::Common; my %config = ( user => "abuser", host => '192.168.1.22', secret => 'guessnot', port => '5038', ); &InitAsterisk; &DoneAsterisk; $top = MainWindow->new(); $button1 = $top->Button( -text => 'Exit', -command => sub { $top->des +troy; },)->pack; print "\n0\n"; MainLoop(); print "\n1\n"; exit; ############################################################ sub InitAsterisk { $asterisk = Asterisk::AMI->new(PeerAddr => $config{host}, PeerPort => $config{port}, Username => $config{user}, Secret => $config{secret}, ); die "Unable to connect to asterisk" unless ($asterisk); print "Asterisk connected\n"; } ############################################################ sub DoneAsterisk { print $asterisk->disconnect; print $asterisk->destroy; print "Asterisk disconnected\n"; die "Unable to DISCONNECT " unless ($asterisk); }
Ubuntu 10.04

Replies are listed 'Best First'.
Re: Tk Mainloop - no exit.
by kcott (Archbishop) on Nov 08, 2010 at 06:56 UTC

    Here's a few things you can do:

    Change the -command to sub { exit } - you don't need to explicitly call destructors.

    Remove the print and exit lines after Mainloop. You should normally only have subroutines, POD, DATA blocks, etc. after MainLoop - not statements such as these.

    Call your subs like sub(); not ⊂ - see perlsub.

    Add use strict; and use warnings; to the top of your code - act on the various messages these report.

    Take a look at the widget demo for examples of writing Perl/Tk code.

    -- Ken

      Thanks Ken,

      I made the cosmetic changes in subroutine calls. Added strict & warnings, and fixed 'explicit package names' warnings. No change in outcome.

      I did not replace the destructor with 'exit' or remove the commands after mainloop, since the whole point it to be able to continue the program after mainloop exits. The problem is that it doesn't exit.

      I do not understand the problem with having code after mainloop exits - 'normal' or not. Everything I know tells me the program is not required to end when the GUI does, anymore that it needs to end after a print statement.

      I'm still clueless.

Re: Tk Mainloop - no exit.
by zentara (Cardinal) on Nov 08, 2010 at 12:13 UTC
    I'm not sure what Asterisk::AMI does, but it seems to be blocking your Tk eventloop. You may need to the Asterisk tasks in a thread, then use Tk::fileevent to read the socket. See Re: Perl Tk and Threads and google for "perl tk threads" for other examples.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      zentara,

      Asterisk::AMI is the management interface to an Asterisk VOIP server. I use it to make calls, inject DTMF, hangup, etc. It can be event driven, but I am not using callbacks. What I don't understand is that I disconnect from it and undef $asterisk, but something is lingering.

      I was hoping there was some way to completely remove any remnants of my call to asterisk::AMI. I'd rather not start new threads.

Re: Tk Mainloop - no exit.
by rrb3942 (Initiate) on Nov 17, 2010 at 03:44 UTC
    Try setting 'Blocking => 0' in your config for Asterisk::AMI. By default the constructor will block when trying to connect/login to asterisk. Setting it 'Blocking => 0' tells it to use a non-blocking connect. Also your DoneAsterisk sub will fail because as soon as Asterisk::AMI goes out of scope it will automatically be destroyed and disconnect from asterisk.