Profile

unixronin: Galen the technomage, from Babylon 5: Crusade (Default)
Unixronin

December 2012

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
3031     

Most Popular Tags

Expand Cut Tags

No cut tags

January 3rd, 2010

unixronin: Galen the technomage, from Babylon 5: Crusade (Default)
Sunday, January 3rd, 2010 10:28 pm

So, I solved the problems with my Perl music player on Gentoo, though I still don't know why it was failing on whitestar, running Gentoo 10.0, while working on babylon5, running a frankelLinux based long ago on Slackware 7, when both are running almost identical versions of Perl, tk, and PerlTk.

What I eventually found out was this.  Originally, I was doing my outside-of-Tk event loop essentially like this:


[initial setup]
$SIG{ALRM} = \&check_status;

$MainWindow = create_UI();
create_playlist();

ualarm(50);
MainLoop();
quit();

sub check_status
{
    [... handle various events here such as checking the MP3
     player process status and handling remote-control events ...]
    check_socket();
    ualarm(50);
}

Now, on babylon5, this was working perfectly.  But on whitestar, once MainLoop() was called it would block, and no SIGALRMs would be handled except when something happened in the interface.

The solution was to ditch the signal handling and do this instead:


[initial setup]
$MainWindow = create_UI();
create_playlist();

$MainWindow->repeat(50 => \&check_status);
MainLoop();
quit();

sub check_status
{
    [... handle various events here such as checking the MP3
     player process status and handling remote-control events ...]
     FIFO for input]
    check_socket();
}

This works reliably in both environments.  As an added bonus, the SIGALRM method would go into an infinite loop on the Gentoo machine (but only there), processing SIGALRMs, after the Tk UI terminated on a Quit command, unless an extra flag was set by the quit() handler to tell check_status() to stop issuing new SIGALRMs.  This does not happen with the repeat() method.

So, the moral of the story:

If you're writing an application using a Tk interface, use Tk's timer mechanism instead of building your own.  Tk's mechanism will work reliably in cooperation with Tk's MainLoop().  Yours may or may not, and if it doesn't, there may be no evident reason why not.

Next problem:  Adding an accurate elapsed-time display.  Oh, and at some point I need to come up with a better name for my player than PerlDJ...

Tags: