triggerbox: basic skeleton for an i/o and stretch thread
This commit is contained in:
parent
7e80111d92
commit
38bf55a1fd
@ -19,6 +19,8 @@
|
||||
#ifndef __ardour_triggerbox_h__
|
||||
#define __ardour_triggerbox_h__
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@ -27,6 +29,7 @@
|
||||
|
||||
#include <glibmm/threads.h>
|
||||
|
||||
#include "pbd/crossthread.h"
|
||||
#include "pbd/pcg_rand.h"
|
||||
#include "pbd/pool.h"
|
||||
#include "pbd/properties.h"
|
||||
@ -330,6 +333,44 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
|
||||
};
|
||||
|
||||
|
||||
class LIBARDOUR_API TriggerBoxThread
|
||||
{
|
||||
public:
|
||||
TriggerBoxThread ();
|
||||
~TriggerBoxThread();
|
||||
|
||||
void summon();
|
||||
void stop();
|
||||
void wait_until_finished();
|
||||
|
||||
static void* _thread_work(void *arg);
|
||||
void* thread_work();
|
||||
|
||||
struct Request {
|
||||
enum Type {
|
||||
Run,
|
||||
Pause,
|
||||
Quit
|
||||
};
|
||||
};
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
Glib::Threads::Mutex request_lock;
|
||||
Glib::Threads::Cond paused;
|
||||
bool should_run;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Add request to thread request queue
|
||||
*/
|
||||
void queue_request (Request::Type r);
|
||||
|
||||
CrossThreadChannel _xthread;
|
||||
};
|
||||
|
||||
|
||||
class LIBARDOUR_API TriggerBox : public Processor
|
||||
{
|
||||
public:
|
||||
@ -476,6 +517,11 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
void process_request (BufferSet&, Request*);
|
||||
|
||||
void reload (BufferSet& bufs, int32_t slot, void* ptr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
namespace Properties {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "pbd/basename.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/pthread_utils.h"
|
||||
#include "pbd/types_convert.h"
|
||||
|
||||
#include "temporal/tempo.h"
|
||||
@ -2342,10 +2343,96 @@ TriggerBox::process_request (BufferSet& bufs, Request* req)
|
||||
void
|
||||
TriggerBox::reload (BufferSet& bufs, int32_t slot, void* ptr)
|
||||
{
|
||||
if (slot >= all_triggers.size()) {
|
||||
if (slot >= (int32_t) all_triggers.size()) {
|
||||
return;
|
||||
}
|
||||
std::cerr << "reload slot " << slot << std::endl;
|
||||
all_triggers[slot]->reload (bufs, ptr);
|
||||
}
|
||||
|
||||
/* Thread */
|
||||
|
||||
TriggerBoxThread::TriggerBoxThread ()
|
||||
: _xthread (true)
|
||||
{
|
||||
if (pthread_create_and_store ("triggerbox thread", &thread, _thread_work, this)) {
|
||||
error << _("Session: could not create triggerbox thread") << endmsg;
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
|
||||
TriggerBoxThread::~TriggerBoxThread()
|
||||
{
|
||||
void* status;
|
||||
queue_request (Request::Quit);
|
||||
pthread_join (thread, &status);
|
||||
}
|
||||
|
||||
void *
|
||||
TriggerBoxThread::_thread_work (void* arg)
|
||||
{
|
||||
SessionEvent::create_per_thread_pool ("tbthread events", 4096);
|
||||
pthread_set_name (X_("tbthread"));
|
||||
return ((TriggerBoxThread *) arg)->thread_work ();
|
||||
}
|
||||
|
||||
void *
|
||||
TriggerBoxThread::thread_work ()
|
||||
{
|
||||
uint32_t err = 0;
|
||||
|
||||
bool disk_work_outstanding = false;
|
||||
RouteList::iterator i;
|
||||
|
||||
while (true) {
|
||||
Temporal::TempoMap::fetch ();
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxThread::queue_request (Request::Type r)
|
||||
{
|
||||
char c = r;
|
||||
if (_xthread.deliver (c) != 1) {
|
||||
/* the x-thread channel is non-blocking
|
||||
* write may fail, but we really don't want to wait
|
||||
* under normal circumstances.
|
||||
*
|
||||
* a lost "run" requests under normal RT operation
|
||||
* is mostly harmless.
|
||||
*
|
||||
* TODO if ardour is freehweeling, wait & retry.
|
||||
* ditto for Request::Type Quit
|
||||
*/
|
||||
assert(1); // we're screwd
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxThread::summon ()
|
||||
{
|
||||
// DEBUG_TRACE (DEBUG::TriggerBoxThread, string_compose ("%1: summon tbthread to run @ %2\n", DEBUG_THREAD_SELF, g_get_monotonic_time()));
|
||||
queue_request (Request::Run);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxThread::stop ()
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (request_lock);
|
||||
// DEBUG_TRACE (DEBUG::TriggerBoxThread, string_compose ("%1: asking tbthread to stop @ %2\n", DEBUG_THREAD_SELF, g_get_monotonic_time()));
|
||||
queue_request (Request::Pause);
|
||||
paused.wait(request_lock);
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBoxThread::wait_until_finished ()
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (request_lock);
|
||||
// DEBUG_TRACE (DEBUG::TriggerBoxThread, string_compose ("%1: waiting for tbthread to finish @ %2\n", DEBUG_THREAD_SELF, g_get_monotonic_time()));
|
||||
queue_request (Request::Pause);
|
||||
paused.wait(request_lock);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user