summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/worker.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-07-31 21:59:21 -0400
committerDavid Robillard <d@drobilla.net>2016-07-31 21:59:21 -0400
commit7c2302651559eda71833c291ddc17f4d590ad95a (patch)
tree32cc32fe32d36acf0693c0834e2ff97b89eefb0e /libs/ardour/ardour/worker.h
parentae71e57e2422466716c0ec68ac841d778cf26e94 (diff)
Support thread-safe LV2 state restoration
The original LV2 state extension required that run() is suspended during restore(). Ardour violates this rule, which can lead to crashes and other issues. The state extension has been updated to allow restoring state in a thread-safe way by using the worker to enqueue state changes. This commit supports that new specification, i.e. supports dropout-free state restoration properly. However, the bug with old plugins that do not use this facility is still not fixed.
Diffstat (limited to 'libs/ardour/ardour/worker.h')
-rw-r--r--libs/ardour/ardour/worker.h36
1 files changed, 26 insertions, 10 deletions
diff --git a/libs/ardour/ardour/worker.h b/libs/ardour/ardour/worker.h
index c83f006f72..6e1a7c91f1 100644
--- a/libs/ardour/ardour/worker.h
+++ b/libs/ardour/ardour/worker.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Paul Davis
+ Copyright (C) 2012-2016 Paul Davis
Author: David Robillard
This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,8 @@
namespace ARDOUR {
+class Worker;
+
/**
An object that needs to schedule non-RT work in the audio thread.
*/
@@ -41,7 +43,7 @@ public:
/**
Do some work in the worker thread.
*/
- virtual int work(uint32_t size, const void* data) = 0;
+ virtual int work(Worker& worker, uint32_t size, const void* data) = 0;
/**
Handle a response from the worker thread in the audio thread.
@@ -50,12 +52,16 @@ public:
};
/**
- A worker thread for non-realtime tasks scheduled in the audio thread.
+ A worker for non-realtime tasks scheduled from another thread.
+
+ A worker may be a separate thread that runs to execute scheduled work
+ asynchronously, or unthreaded, in which case work is executed immediately
+ upon scheduling by the calling thread.
*/
class LIBARDOUR_API Worker
{
public:
- Worker(Workee* workee, uint32_t ring_size);
+ Worker(Workee* workee, uint32_t ring_size, bool threaded=true);
~Worker();
/**
@@ -75,6 +81,16 @@ public:
*/
void emit_responses();
+ /**
+ Enable or disable synchronous execution.
+
+ If enabled, all work is performed immediately in schedule() regardless
+ of whether or not the worker is threaded. This is used for exporting,
+ where we want to temporarily execute all work synchronously but the
+ worker is typically used threaded for live rolling.
+ */
+ void set_synchronous(bool synchronous) { _synchronous = synchronous; }
+
private:
void run();
/**
@@ -83,19 +99,19 @@ private:
Handle the unlikley edge-case, if we're called in between the
responder writing 'size' and 'data'.
- @param rb the ringbuffer to check
- @return true if the message is complete, false otherwise
- */
+ @param rb the ringbuffer to check
+ @return true if the message is complete, false otherwise
+ */
bool verify_message_completeness(RingBuffer<uint8_t>* rb);
Workee* _workee;
RingBuffer<uint8_t>* _requests;
RingBuffer<uint8_t>* _responses;
uint8_t* _response;
- PBD::Semaphore _sem;
- bool _exit;
+ PBD::Semaphore _sem;
Glib::Threads::Thread* _thread;
-
+ bool _exit;
+ bool _synchronous;
};
} // namespace ARDOUR