Suspend background processes while writing to shared data structures
This commit is contained in:
parent
6eec3440cc
commit
829bfeabe8
1
Build.PL
1
Build.PL
@ -19,6 +19,7 @@ my %prereqs = qw(
|
||||
Scalar::Util 0
|
||||
Test::Harness 0
|
||||
Test::More 0
|
||||
Thread::Semaphore 0
|
||||
IO::Scalar 0
|
||||
Time::HiRes 0
|
||||
);
|
||||
|
@ -7,6 +7,7 @@ use File::Basename qw(basename dirname);
|
||||
use List::Util qw(sum first);
|
||||
use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale);
|
||||
use threads::shared qw(shared_clone);
|
||||
use Thread::Semaphore;
|
||||
use Wx qw(:button :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc :panel :sizer :toolbar :window);
|
||||
use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED
|
||||
EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL
|
||||
@ -39,10 +40,12 @@ our $PROCESS_COMPLETED_EVENT : shared = Wx::NewEventType;
|
||||
|
||||
use constant CANVAS_SIZE => [335,335];
|
||||
use constant FILAMENT_CHOOSERS_SPACING => 3;
|
||||
use constant PROCESS_DELAY => 1 * 1000; # milliseconds
|
||||
use constant PROCESS_DELAY => 0.5 * 1000; # milliseconds
|
||||
|
||||
my $PreventListEvents = 0;
|
||||
|
||||
my $sema = Thread::Semaphore->new;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my ($parent) = @_;
|
||||
@ -566,6 +569,7 @@ sub rotate {
|
||||
$model_object->update_bounding_box;
|
||||
|
||||
# update print and start background processing
|
||||
$self->suspend_background_process;
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
$self->schedule_background_process;
|
||||
|
||||
@ -602,6 +606,7 @@ sub changescale {
|
||||
$model_object->update_bounding_box;
|
||||
|
||||
# update print and start background processing
|
||||
$self->suspend_background_process;
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
$self->schedule_background_process;
|
||||
|
||||
@ -648,6 +653,8 @@ sub split_object {
|
||||
return;
|
||||
}
|
||||
|
||||
$self->suspend_background_process;
|
||||
|
||||
# create a bogus Model object, we only need to instantiate the new Model::Object objects
|
||||
my $new_model = Slic3r::Model->new;
|
||||
|
||||
@ -700,7 +707,9 @@ sub schedule_background_process {
|
||||
sub async_apply_config {
|
||||
my ($self) = @_;
|
||||
|
||||
# TODO: pause process thread before applying new config
|
||||
# pause process thread before applying new config
|
||||
# since we don't want to touch data that is being used by the threads
|
||||
$self->suspend_background_process;
|
||||
|
||||
# apply new config
|
||||
my $invalidated = $self->{print}->apply_config($self->skeinpanel->config);
|
||||
@ -721,6 +730,8 @@ sub async_apply_config {
|
||||
sub start_background_process {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->resume_background_process;
|
||||
|
||||
return if !$Slic3r::have_threads;
|
||||
return if !@{$self->{objects}};
|
||||
return if $self->{process_thread};
|
||||
@ -751,6 +762,10 @@ sub start_background_process {
|
||||
Slic3r::thread_cleanup();
|
||||
threads->exit();
|
||||
};
|
||||
local $SIG{'STOP'} = sub {
|
||||
$sema->down;
|
||||
$sema->up;
|
||||
};
|
||||
|
||||
eval {
|
||||
$self->{print}->process;
|
||||
@ -790,6 +805,19 @@ sub stop_background_process {
|
||||
}
|
||||
}
|
||||
|
||||
sub suspend_background_process {
|
||||
my ($self) = @_;
|
||||
|
||||
$sema->down;
|
||||
$_->kill('STOP') for grep $_, $self->{process_thread}, $self->{export_thread};
|
||||
}
|
||||
|
||||
sub resume_background_process {
|
||||
my ($self) = @_;
|
||||
|
||||
$sema->up;
|
||||
}
|
||||
|
||||
sub export_gcode {
|
||||
my $self = shift;
|
||||
|
||||
@ -885,6 +913,10 @@ sub on_process_completed {
|
||||
Slic3r::thread_cleanup();
|
||||
threads->exit();
|
||||
};
|
||||
local $SIG{'STOP'} = sub {
|
||||
$sema->down;
|
||||
$sema->up;
|
||||
};
|
||||
|
||||
eval {
|
||||
$_thread_self->{print}->export_gcode(output_file => $_thread_self->{export_gcode_output_file});
|
||||
|
Loading…
Reference in New Issue
Block a user