summaryrefslogtreecommitdiffstats
path: root/src/server/Worker.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-07-31 23:00:45 -0400
committerDavid Robillard <d@drobilla.net>2016-07-31 23:00:45 -0400
commit7eb24a2761deb9604f1c6b813e6de69876088f9e (patch)
tree919062cdc82d8c6a0697249bf95e6668c19eae83 /src/server/Worker.cpp
parenta3b28f2924801bd59ea7924a652247269e6af928 (diff)
downloadingen-7eb24a2761deb9604f1c6b813e6de69876088f9e.tar.gz
ingen-7eb24a2761deb9604f1c6b813e6de69876088f9e.tar.bz2
ingen-7eb24a2761deb9604f1c6b813e6de69876088f9e.zip
Support thread-safe state restoration
Diffstat (limited to 'src/server/Worker.cpp')
-rw-r--r--src/server/Worker.cpp39
1 files changed, 32 insertions, 7 deletions
diff --git a/src/server/Worker.cpp b/src/server/Worker.cpp
index a89bd4b3..1ff7a89c 100644
--- a/src/server/Worker.cpp
+++ b/src/server/Worker.cpp
@@ -1,6 +1,6 @@
/*
This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
+ Copyright 2007-2016 David Robillard <http://drobilla.net/>
Ingen is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free
@@ -46,11 +46,27 @@ schedule(LV2_Worker_Schedule_Handle handle,
return worker->request(block, size, data);
}
+static LV2_Worker_Status
+schedule_sync(LV2_Worker_Schedule_Handle handle,
+ uint32_t size,
+ const void* data)
+{
+ LV2Block* block = (LV2Block*)handle;
+ Engine& engine = block->parent_graph()->engine();
+ Worker* worker = engine.sync_worker();
+
+ return worker->request(block, size, data);
+}
+
LV2_Worker_Status
Worker::request(LV2Block* block,
uint32_t size,
const void* data)
{
+ if (_synchronous) {
+ return block->work(size, data);
+ }
+
Engine& engine = block->parent_graph()->engine();
if (_requests.write_space() < sizeof(MessageHeader) + size) {
engine.log().error("Work request ring overflow\n");
@@ -83,7 +99,7 @@ Worker::Schedule::feature(World* world, Node* n)
LV2_Worker_Schedule* data = (LV2_Worker_Schedule*)malloc(
sizeof(LV2_Worker_Schedule));
data->handle = block;
- data->schedule_work = schedule;
+ data->schedule_work = synchronous ? schedule_sync : schedule;
LV2_Feature* f = (LV2_Feature*)malloc(sizeof(LV2_Feature));
f->URI = LV2_WORKER__schedule;
@@ -92,22 +108,31 @@ Worker::Schedule::feature(World* world, Node* n)
return SPtr<LV2_Feature>(f, &free_feature);
}
-Worker::Worker(Log& log, uint32_t buffer_size)
- : _schedule(new Schedule())
+Worker::Worker(Log& log, uint32_t buffer_size, bool synchronous)
+ : _schedule(new Schedule(synchronous))
, _log(log)
, _sem(0)
, _requests(buffer_size)
, _responses(buffer_size)
, _buffer((uint8_t*)malloc(buffer_size))
, _buffer_size(buffer_size)
- , _thread(&Worker::run, this)
-{}
+ , _thread(nullptr)
+ , _exit_flag(false)
+ , _synchronous(synchronous)
+{
+ if (!synchronous) {
+ _thread = new std::thread(&Worker::run, this);
+ }
+}
Worker::~Worker()
{
_exit_flag = true;
_sem.post();
- _thread.join();
+ if (_thread) {
+ _thread->join();
+ delete _thread;
+ }
free(_buffer);
}