From 8d171a297e01c19c7c5357deaf79ab417fdefad0 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 11 Jul 2013 16:17:36 +0200 Subject: [PATCH] Add thread cleanup to avoid double destruction of shared XS data --- lib/Slic3r.pm | 21 ++++++++++++++++----- lib/Slic3r/GUI/Plater.pm | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 00d19713..a8b0a540 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -87,11 +87,9 @@ sub parallelize { $q->enqueue(@items, (map undef, 1..$Config->threads)); my $thread_cb = sub { - # prevent destruction of shared objects - no warnings 'redefine'; - *Slic3r::ExPolygon::XS::DESTROY = sub {}; - - return $params{thread_cb}->($q); + my $result = $params{thread_cb}->($q); + Slic3r::thread_cleanup(); + return $result; }; @_ = (); @@ -103,6 +101,19 @@ sub parallelize { } } +# call this at the very end of each thread (except the main one) +# so that it does not try to free existing objects. +# at that stage, existing objects are only those that we +# inherited at the thread creation (thus shared) and those +# that we are returning: destruction will be handled by the +# main thread in both cases. +sub thread_cleanup { + # prevent destruction of shared objects + no warnings 'redefine'; + *Slic3r::ExPolygon::XS::DESTROY = sub {}; + *Slic3r::Point::XS::DESTROY = sub {}; +} + sub encode_path { my ($filename) = @_; return encode('locale_fs', $filename); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index dee59215..ef75ddb3 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -570,6 +570,7 @@ sub export_gcode { }); }, ); + Slic3r::thread_cleanup(); }); $self->statusbar->SetCancelCallback(sub { $self->{export_thread}->kill('KILL')->join; @@ -744,6 +745,8 @@ sub make_thumbnail { } else { $self->on_thumbnail_made($obj_idx); } + + Slic3r::thread_cleanup() if $Slic3r::have_threads; }; @_ = ();