From 66f1ae003f4d0a4b042a1cd6d697c2c14724d5cd Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 8 Jun 2017 18:53:33 +0200 Subject: [PATCH] A little simplification of the Perl side threading: Only single level Perl worker threads are allowed. --- lib/Slic3r.pm | 58 ++++++++++---------------------------- lib/Slic3r/GUI.pm | 1 - lib/Slic3r/Print/Object.pm | 5 ---- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 2de7a35fb..8d0de99cd 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -91,11 +91,9 @@ use constant LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER => 0.15; # use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR; use constant INFILL_OVERLAP_OVER_SPACING => 0.3; -# Keep track of threads we created. Each thread keeps its own list of threads it spwaned. -my @my_threads = (); -my @threads : shared = (); +# Keep track of threads we created. Perl worker threads shall not create further threads. +my @threads = (); my $pause_sema = Thread::Semaphore->new; -my $parallel_sema; my $paused = 0; # Set the logging level at the Slic3r XS module. @@ -104,19 +102,11 @@ set_logging_level($Slic3r::loglevel); sub spawn_thread { my ($cb) = @_; - - my $parent_tid = threads->tid; - lock @threads; - @_ = (); my $thread = threads->create(sub { - @my_threads = (); - - Slic3r::debugf "Starting thread %d (parent: %d)...\n", threads->tid, $parent_tid; + Slic3r::debugf "Starting thread %d...\n", threads->tid; local $SIG{'KILL'} = sub { Slic3r::debugf "Exiting thread %d...\n", threads->tid; - $parallel_sema->up if $parallel_sema; - kill_all_threads(); Slic3r::thread_cleanup(); threads->exit(); }; @@ -126,7 +116,6 @@ sub spawn_thread { }; $cb->(); }); - push @my_threads, $thread->tid; push @threads, $thread->tid; return $thread; } @@ -143,13 +132,6 @@ sub spawn_thread { # object in a thread, make sure the main thread still holds a # reference so that it won't be destroyed in thread. sub thread_cleanup { - return if !$Slic3r::have_threads; - - if (threads->tid == 0) { - warn "Calling thread_cleanup() from main thread\n"; - return; - } - # prevent destruction of shared objects no warnings 'redefine'; *Slic3r::BridgeDetector::DESTROY = sub {}; @@ -169,9 +151,6 @@ sub thread_cleanup { *Slic3r::ExtrusionPath::Collection::DESTROY = sub {}; *Slic3r::ExtrusionSimulator::DESTROY = sub {}; *Slic3r::Flow::DESTROY = sub {}; -# Fillers are only being allocated in worker threads, which are not going to be forked. -# Therefore the Filler instances shall be released at the end of the thread. -# *Slic3r::Filler::DESTROY = sub {}; *Slic3r::GCode::DESTROY = sub {}; *Slic3r::GCode::PlaceholderParser::DESTROY = sub {}; *Slic3r::GCode::Sender::DESTROY = sub {}; @@ -200,44 +179,37 @@ sub thread_cleanup { return undef; # this prevents a "Scalars leaked" warning } -sub get_running_threads { - return grep defined($_), map threads->object($_), @_; +sub _get_running_threads { + return grep defined($_), map threads->object($_), @threads; } sub kill_all_threads { - # if we're the main thread, we send SIGKILL to all the running threads - if (threads->tid == 0) { - lock @threads; - foreach my $thread (get_running_threads(@threads)) { - Slic3r::debugf "Thread %d killing %d...\n", threads->tid, $thread->tid; - $thread->kill('KILL'); - } - - # unlock semaphore before we block on wait - # otherwise we'd get a deadlock if threads were paused - resume_all_threads(); + # Send SIGKILL to all the running threads to let them die. + foreach my $thread (_get_running_threads) { + Slic3r::debugf "Thread %d killing %d...\n", threads->tid, $thread->tid; + $thread->kill('KILL'); } - + # unlock semaphore before we block on wait + # otherwise we'd get a deadlock if threads were paused + resume_all_threads(); # in any thread we wait for our children - foreach my $thread (get_running_threads(@my_threads)) { + foreach my $thread (_get_running_threads) { Slic3r::debugf " Thread %d waiting for %d...\n", threads->tid, $thread->tid; $thread->join; # block until threads are killed Slic3r::debugf " Thread %d finished waiting for %d...\n", threads->tid, $thread->tid; } - @my_threads = (); + @threads = (); } sub pause_all_threads { return if $paused; - lock @threads; $paused = 1; $pause_sema->down; - $_->kill('STOP') for get_running_threads(@threads); + $_->kill('STOP') for _get_running_threads; } sub resume_all_threads { return unless $paused; - lock @threads; $paused = 0; $pause_sema->up; } diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 9aee9bafe..2e9bddd50 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -350,7 +350,6 @@ sub check_version { my $response = $ua->get('http://slic3r.org/updatecheck'); Wx::PostEvent($self, Wx::PlThreadEvent->new(-1, $VERSION_CHECK_EVENT, threads::shared::shared_clone([ $response->is_success, $response->decoded_content, $manual_check ]))); - Slic3r::thread_cleanup(); })->detach; } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index e7fe54623..194905461 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -14,11 +14,6 @@ use Slic3r::Surface ':types'; # If enabled, phases of prepare_infill will be written into SVG files to an "out" directory. our $SLIC3R_DEBUG_SLICE_PROCESSING = 0; -sub region_volumes { - my $self = shift; - return [ map $self->get_region_volumes($_), 0..($self->region_count - 1) ]; -} - sub layers { my $self = shift; return [ map $self->get_layer($_), 0..($self->layer_count - 1) ];