package My::ThreadManager; ########################################################### # USES ########################################################### use strict; use warnings; use base 'Exporter'; use Data::Dumper; use threads; use threads::shared; use Thread::Queue; use My::Globals; use My::ThreadWorker; use feature qw(say); use constant { EV_NONE => 0, EV_KILL => 1, EV_WORK_START => 2, EV_WORK_CANCEL => 3, EV_WORK_FINISH => 4 }; use constant { STATE_IDLE => 0, STATE_WORK => 1 }; ########################################################### # EXPORT ########################################################### our @EXPORT = qw(createMyThread killMyThread evWorkStart evWorkCancel isWorkFinished shallWorkBeCancelled ); ########################################################### # VARIABLES ########################################################### my $thread; my $thread_event:shared = EV_NONE; my $thread_state:shared = STATE_IDLE; my $q = Thread::Queue->new(); ########################################################### # PUBLIC FUNCTIONS ########################################################### sub createMyThread { $thread = threads->create( \&execMyThread ); } sub execMyThread { STATE_IDLE: $thread_state = STATE_IDLE; say "STATE_IDLE"; while(1) { if( $thread_event == EV_WORK_START ) { say "EV_WORK_START"; $thread_event = EV_NONE; goto STATE_WORK; } elsif( $thread_event == EV_KILL ) { say "EV_KILL"; $thread_event = EV_NONE; return; } else { # wait select(undef,undef,undef,0.1); } } STATE_WORK: $thread_state = STATE_WORK; say "STATE_WORK"; while(1) { if( ($thread_event == EV_WORK_FINISH) || ($thread_event == EV_WORK_CANCEL) ) { say "EV_WORK_FINISH" if( $thread_event == EV_WORK_FINISH ); say "EV_WORK_CANCEL" if( $thread_event == EV_WORK_CANCEL ); $thread_event = EV_NONE; goto STATE_IDLE; } elsif( $thread_event == EV_KILL ) { say "EV_KILL"; $thread_event = EV_NONE; return; } else { my %thread_data; select(undef,undef,undef,0.1); while( my $thread_data_str1 = $q->dequeue ) { %thread_data = %{ eval $thread_data_str1 }; }; if( &work(\%thread_data) == CANCEL ) { $thread_event = EV_WORK_CANCEL; } else { $thread_event = EV_WORK_FINISH; } } } } sub killMyThread { $thread_event = EV_KILL; $thread->join; exit 0; } sub evWorkStart { my $ref_thread_data = $_[0]; my $thread_data_str1 = ""; $Data::Dumper::Varname = "thread_data_str"; $thread_data_str1 = Dumper($ref_thread_data); $q->enqueue( $thread_data_str1 ); $q->enqueue( undef ); $thread_event = EV_WORK_START; while( $thread_state != STATE_WORK ) { select(undef, undef, undef, 0.1); } } sub evWorkCancel { $thread_event = EV_WORK_CANCEL; while( $thread_state != STATE_IDLE ) { select(undef, undef, undef, 0.1); } } sub isWorkFinished { if( $thread_state == STATE_IDLE ) { return TRUE; } else { return FALSE; } } sub shallWorkBeCancelled { if( $thread_event == EV_WORK_CANCEL ) { return TRUE; } else { return FALSE; } } ########################################################### # PRIVATE FUNCTIONS ########################################################### # NONE 1;