Changeset 11027
- Timestamp:
- 03/09/10 02:28:50 (2 years ago)
- Location:
- trunk/Padre/lib/Padre
- Files:
-
- 2 edited
-
SlaveDriver.pm (modified) (12 diffs)
-
TaskManager.pm (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Padre/lib/Padre/SlaveDriver.pm
r11023 r11027 40 40 our $VERSION = '0.58'; 41 41 42 # According to Wx docs, 43 # this MUST be loaded before Wx, 42 # According to Wx docs this MUST be loaded before Wx, 44 43 # so this also happens in the script. 45 44 use threads; … … 61 60 The constructor returns a C<Padre::SlaveDriver> object. 62 61 C<Padre::SlaveDriver> is a singleton. 62 63 63 An object is instantiated when the editor object is created. 64 64 … … 69 69 70 70 sub new { 71 return $SlaveDriver if defined $SlaveDriver; 72 71 73 my $class = shift; 72 return $SlaveDriver if defined $SlaveDriver;73 @_ = (); 74 @_ = (); 75 74 76 $SlaveDriver = bless { 75 77 cmd_queue => Thread::Queue->new, … … 77 79 task_queue => Thread::Queue->new, 78 80 } => $class; 79 $SlaveDriver->_init_events; 80 81 # There is no database/locking protection 82 # here, so this must happen before we make 83 # a long-term connection to the database. 81 82 # Wx must be loaded before this code fires 83 require Padre::Wx; 84 $TASK_DONE_EVENT = Wx::NewEventType() unless defined $TASK_DONE_EVENT; 85 $TASK_START_EVENT = Wx::NewEventType() unless defined $TASK_START_EVENT; 86 87 # Because the following code spawns the slave master, 88 # we need to wrap an database anti-lock around it. 89 my $locked = Padre::DB->can('connected') && Padre::DB->connected; 90 Padre::DB->commit if $locked; 91 92 # Create the "slave master" top level thread. 84 93 $SlaveDriver->{master} = threads->create( 85 94 \&_slave_driver_loop, … … 88 97 ); 89 98 99 # If we were previously in a database lock restore it 100 # so that lock management doesn't freak out. 101 Padre::DB->begin if $locked; 102 90 103 return $SlaveDriver; 91 104 } … … 99 112 } 100 113 101 # done late so that the full Wx has been loaded for sure102 sub _init_events {103 $TASK_DONE_EVENT = Wx::NewEventType() if not defined $TASK_DONE_EVENT;104 $TASK_START_EVENT = Wx::NewEventType() if not defined $TASK_START_EVENT;105 }106 107 114 =pod 108 115 … … 119 126 my $self = shift; 120 127 my $task_manager = shift; 128 121 129 require Storable; 122 $self->{cmd_queue}->enqueue( Storable::freeze( [ $task_manager->task_queue ] ) ); 123 return threads->object( $self->{tid_queue}->dequeue ); 130 $self->{cmd_queue}->enqueue( 131 Storable::freeze( [ $task_manager->task_queue ] ) 132 ); 133 134 return threads->object( 135 $self->{tid_queue}->dequeue 136 ); 124 137 } 125 138 … … 152 165 sub cleanup { 153 166 my $self = shift; 167 154 168 if ( defined $self->{master} and defined $self->{cmd_queue} ) { 155 169 $self->{cmd_queue}->enqueue('STOP'); 170 156 171 require Time::HiRes; 157 172 Time::HiRes::usleep(5000); # 5 milli-sec 173 158 174 if ( $self->{master}->is_joinable ) { 159 175 $self->{master}->join; … … 165 181 166 182 sub DESTROY { 167 $_[0]->cleanup; 168 } 169 170 ########################## 183 shift->cleanup; 184 } 185 186 187 188 189 190 ###################################################################### 171 191 # Worker thread main loop 192 172 193 sub _worker_loop { 173 my ( $queue) = @_;174 @_ = (); # hack to avoid "Scalars leaked"194 my ( $queue ) = @_; 195 @_ = (); # Hack to avoid "Scalars leaked" 175 196 176 197 require Storable; … … 178 199 179 200 # Set the thread-specific main-window pointer 180 my $ main= Padre->ide->wx;181 182 # warn threads->tid() . " -- Hi, I'm a thread.";201 my $wx = Padre->ide->wx; 202 203 # warn threads->tid() . " -- Hi, I'm a thread."; 183 204 184 205 while ( my $frozen_task = $queue->dequeue ) { 185 206 186 # warn threads->tid() . " -- got task.";187 188 # warn("THREAD TERMINATING"), return 1 if not ref($task) and $task eq 'STOP';207 # warn threads->tid() . " -- got task."; 208 209 # warn("THREAD TERMINATING"), return 1 if not ref($task) and $task eq 'STOP'; 189 210 return 1 if not ref($frozen_task) and $frozen_task eq 'STOP'; 190 211 191 212 my $task = Padre::Task->deserialize( \$frozen_task ); 192 $task->{__thread_id} = threads->tid(); 193 194 my $thread_start_event = 195 Wx::PlThreadEvent->new( -1, $TASK_START_EVENT, $task->{__thread_id} . ";" . ref($task) ); 196 Wx::PostEvent( $main, $thread_start_event ); 213 $task->{__thread_id} = threads->tid; 214 215 my $thread_start_event = Wx::PlThreadEvent->new( 216 -1, 217 $TASK_START_EVENT, 218 $task->{__thread_id} . ";" . ref($task), 219 ); 220 Wx::PostEvent( $wx, $thread_start_event ); 197 221 198 222 # RUN … … 203 227 $task->serialize( \$frozen_task ); 204 228 205 my $thread_done_event = Wx::PlThreadEvent->new( -1, $TASK_DONE_EVENT, $frozen_task ); 206 Wx::PostEvent( $main, $thread_done_event ); 207 208 #warn threads->tid() . " -- done with task."; 209 } 210 229 my $thread_done_event = Wx::PlThreadEvent->new( 230 -1, 231 $TASK_DONE_EVENT, 232 $frozen_task, 233 ); 234 Wx::PostEvent( $wx, $thread_done_event ); 235 236 # warn threads->tid() . " -- done with task."; 237 } 211 238 } 212 239 … … 217 244 while ( my $args = $inqueue->dequeue ) { # args is frozen [$main, $queue] 218 245 last if $args eq 'STOP'; 219 my $task_queue = Padre::SlaveDriver->new->task_queue; 220 221 # Apply the database anti-lock, so there are no active DBI connection 222 # handles at the time we spawn the thread. 223 # If Padre::DB is not loaded at all, the following returns false and 224 # we never make the calls to the non-existant class. 225 my $locked = Padre::DB->can('connected') && Padre::DB->connected; 226 if ( $locked ) { 227 Padre::DB->commit; 228 } 229 230 # Do the actual thread spawn 246 my $task_queue = Padre::SlaveDriver->new->task_queue; 231 247 my $worker_thread = threads->create( \&_worker_loop, $task_queue ); 232 233 # Release the anti-lock on the database234 if ( $locked ) {235 Padre::DB->begin;236 }237 238 # Continue onwards with thready stuff239 248 $outqueue->enqueue($worker_thread->tid); 240 249 } 250 241 251 return 1; 242 252 } -
trunk/Padre/lib/Padre/TaskManager.pm
r10997 r11027 96 96 # communicate to the main thread over the life of a service. 97 97 our $SERVICE_POLL_EVENT : shared; 98 BEGIN { $SERVICE_POLL_EVENT = Wx::NewEventType; } 98 BEGIN { 99 $SERVICE_POLL_EVENT = Wx::NewEventType; 100 } 99 101 100 102 # remember whether the event handlers were initialized... … … 109 111 sub new { 110 112 my $class = shift; 113 $DB::single = 1; 111 114 112 115 return $SINGLETON if defined $SINGLETON; 116 117 my $driver = Padre::SlaveDriver->new; 113 118 114 119 my $self = $SINGLETON = bless { … … 120 125 workers => [], 121 126 122 # grab a copy of the task_queue that's now handled by the slave driver123 task_queue => Padre::SlaveDriver->new()->task_queue,127 # Grab a copy of the task_queue that's now handled by the slave driver 128 task_queue => $driver->task_queue, 124 129 running_tasks => {}, 125 130 }, $class; … … 144 149 $REAP_TIMER = Wx::Timer->new( $main, $timerid ); 145 150 Wx::Event::EVT_TIMER( 146 $main, $timerid, sub { $SINGLETON->reap(); }, 151 $main, $timerid, sub { 152 $SINGLETON->reap; 153 }, 147 154 ); 148 $REAP_TIMER->Start( $self->reap_interval, Wx::wxTIMER_CONTINUOUS ); 155 $REAP_TIMER->Start( 156 $self->reap_interval, 157 Wx::wxTIMER_CONTINUOUS, 158 ); 149 159 } 150 160 … … 423 433 424 434 # cleanup master thread, too 425 Padre::SlaveDriver->new->cleanup ();435 Padre::SlaveDriver->new->cleanup; 426 436 427 437 # didn't work the nice way? … … 503 513 504 514 sub workers { 505 my $self = shift; 506 return @{ $self->{workers} }; 515 $_[0]->{workers}; 507 516 } 508 517 … … 522 531 523 532 sub on_task_done_event { 524 my ( $main, $event ) = @_; @_ = (); # hack to avoid "Scalars leaked" 533 my ( $main, $event ) = @_; 534 @_ = (); # hack to avoid "Scalars leaked" 525 535 my $frozen = $event->GetData; 526 536
Note: See TracChangeset
for help on using the changeset viewer.
