# '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"); }