/*
- 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
#include <glibmm/threads.h>
#include "pbd/ringbuffer.h"
-#include "pbd/semaphore.h"
+#include "pbd/semutils.h"
#include "ardour/libardour_visibility.h"
namespace ARDOUR {
+class Worker;
+
/**
An object that needs to schedule non-RT work in the audio thread.
*/
/**
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.
};
/**
- 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();
/**
*/
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();
/**
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
- */
- 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;
- Glib::Threads::Thread* _thread;
-
+ @param rb the ringbuffer to check
+ @return true if the message is complete, false otherwise
+ */
+ bool verify_message_completeness(PBD::RingBuffer<uint8_t>* rb);
+
+ Workee* _workee;
+ PBD::RingBuffer<uint8_t>* _requests;
+ PBD::RingBuffer<uint8_t>* _responses;
+ uint8_t* _response;
+ PBD::Semaphore _sem;
+ Glib::Threads::Thread* _thread;
+ bool _exit;
+ bool _synchronous;
};
} // namespace ARDOUR