# 'manager' loggin thread: communication queues initialization
# and thread creation
#
my ($mgr_id, $mgr_req_q, $mgr_ack_q);
$mgr_req_q = new Thread::Queue;
$mgr_ack_q = new Thread::Queue;
$mgr_id = threads->create("SerialLogger::manager");
# Main window
#
my $w_top = MainWindow->new(-title => "COM Monitor");
...
...
# tk stuff
MainLoop;
# Clean up and exit (after MainLoop returned)
$mgr_req_q->enqueue("die");
$mgr_id->join();
exit(0);
####
# worker thread function
#
sub serial_logger
{
my ($num, $fh) = @_;
my $state = "idle";
my $mycom;
print "worker $num born\n" if $THR_DEBUG;
while (1)
{
if (my $msg = $worker_req_q[$num]->dequeue_nb())
{
print "worker $num got '$msg'\n" if $THR_DEBUG;
if ($msg eq "die")
{
$worker_ack_q[$num]->enqueue("OK");
return;
}
if ($state eq "idle")
{
my $ret;
if ($msg =~ /^open\s(.*)$/)
{
($ret, $mycom) = @{open_com($1)};
$worker_ack_q[$num]->enqueue($ret);
}
elsif ($msg eq "run")
{
$state = "running";
}
}
elsif ($state eq "running")
{
if ($msg eq "stop")
{
clean();
$state = "idle";
}
}
}
if ($state eq "running" and $mycom->{is_open} == 1)
{
eval
{
my ($rb, $byte) = $mycom->{port}->read(1);
if ($rb > 0)
{
my $s = gettimeofday();
my $prt = join(",", $mycom->{name}, ord($byte), "$s");
print $fh "$prt\n";
}
};
if ($@)
{
$state = "idle";
}
}
else
{
select(undef, undef, undef, 0.01);
}
}
}
##
##
elsif ($msg =~ /^open\s(.*)$/)
{
my $thrid = threads->create("serial_logger", $n_workers, $mgr_fh);
push(@worker_id, $thrid);
$worker_req_q[$n_workers]->enqueue($msg);
my $ret = $worker_ack_q[$n_workers]->dequeue;
$mgr_ack_q->enqueue($ret);
++$n_workers;
}
elsif ($msg eq "run")
{
$mgr_state = "running";
broadcast_to_workers("run");
}