cross-thread handling of SessionEvent allocation/deallocation, with widespread consequences
git-svn-id: svn://localhost/ardour2/branches/3.0@6283 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
478fd92039
commit
4a3d7877f6
|
@ -264,6 +264,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
|
|||
GainMeter::setup_slider_pix ();
|
||||
RouteTimeAxisView::setup_slider_pix ();
|
||||
SendProcessorEntry::setup_slider_pix ();
|
||||
SessionEvent::create_per_thread_pool ("GUI", 512);
|
||||
|
||||
} catch (failed_constructor& err) {
|
||||
error << _("could not initialize Ardour.") << endmsg;
|
||||
|
|
|
@ -880,6 +880,7 @@ void *
|
|||
Editor::_import_thread (void *arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Import"));
|
||||
SessionEvent::create_per_thread_pool ("import events", 64);
|
||||
|
||||
Editor *ed = (Editor *) arg;
|
||||
return ed->import_thread ();
|
||||
|
|
|
@ -3653,6 +3653,8 @@ void*
|
|||
Editor::_freeze_thread (void* arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Freeze"));
|
||||
SessionEvent::create_per_thread_pool ("freeze events", 64);
|
||||
|
||||
return static_cast<Editor*>(arg)->freeze_thread ();
|
||||
}
|
||||
|
||||
|
|
|
@ -338,6 +338,7 @@ void*
|
|||
Editor::timefx_thread (void *arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("TimeFX"));
|
||||
SessionEvent::create_per_thread_pool ("timefx events", 64);
|
||||
|
||||
TimeFXDialog* tsd = static_cast<TimeFXDialog*>(arg);
|
||||
|
||||
|
|
|
@ -734,6 +734,7 @@ void*
|
|||
freesound_search_thread_entry (void* arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Freesound Search"));
|
||||
SessionEvent::create_per_thread_pool ("freesound events", 64);
|
||||
|
||||
static_cast<SoundFileBrowser*>(arg)->freesound_search_thread ();
|
||||
|
||||
|
@ -763,6 +764,10 @@ SoundFileBrowser::freesound_search_clicked ()
|
|||
void
|
||||
SoundFileBrowser::freesound_search_thread()
|
||||
{
|
||||
#if 0
|
||||
|
||||
THIS IS ALL TOTALLY THREAD-ILLEGAL ... YOU CANNOT DO GTK STUFF IN THIS THREAD
|
||||
|
||||
#ifdef FREESOUND
|
||||
freesound_list->clear();
|
||||
|
||||
|
@ -810,6 +815,8 @@ SoundFileBrowser::freesound_search_thread()
|
|||
canceling = false;
|
||||
freesound_search_btn.set_label(_("Start Downloading"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vector<ustring>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "ardour/analyser.h"
|
||||
#include "ardour/audiofilesource.h"
|
||||
#include "ardour/session_event.h"
|
||||
#include "ardour/transient_detector.h"
|
||||
|
||||
#include "pbd/pthread_utils.h"
|
||||
|
@ -76,6 +77,7 @@ void
|
|||
Analyser::work ()
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), string ("analyser-") + to_string (pthread_self(), std::dec));
|
||||
SessionEvent::create_per_thread_pool ("Analyser", 64);
|
||||
|
||||
while (true) {
|
||||
analysis_queue_lock.lock ();
|
||||
|
|
|
@ -98,18 +98,17 @@ struct SessionEvent {
|
|||
return e1->before (*e2);
|
||||
}
|
||||
|
||||
void *operator new (size_t) {
|
||||
return pool.alloc ();
|
||||
}
|
||||
|
||||
void operator delete (void *ptr, size_t /*size*/) {
|
||||
pool.release (ptr);
|
||||
}
|
||||
void* operator new (size_t);
|
||||
void operator delete (void *ptr, size_t /*size*/);
|
||||
|
||||
static const nframes_t Immediate = 0;
|
||||
|
||||
static void create_per_thread_pool (const std::string& n, unsigned long nitems);
|
||||
static void init_event_pool ();
|
||||
|
||||
private:
|
||||
static MultiAllocSingleReleasePool pool;
|
||||
static PerThreadPool* pool;
|
||||
CrossThreadPool* own_pool;
|
||||
};
|
||||
|
||||
class SessionEventManager {
|
||||
|
@ -120,8 +119,8 @@ class SessionEventManager {
|
|||
void add_event (nframes64_t action_frame, SessionEvent::Type type, nframes64_t target_frame = 0);
|
||||
void remove_event (nframes64_t frame, SessionEvent::Type type);
|
||||
void clear_events (SessionEvent::Type type);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
RingBuffer<SessionEvent*> pending_events;
|
||||
typedef std::list<SessionEvent *> Events;
|
||||
|
|
|
@ -136,6 +136,8 @@ _thread_init_callback (void * /*arg*/)
|
|||
*/
|
||||
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Audioengine"), 4096);
|
||||
SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
|
||||
|
||||
MIDI::JACK_MidiPort::set_process_thread (pthread_self());
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ void *
|
|||
Butler::_thread_work (void* arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Butler"));
|
||||
SessionEvent::create_per_thread_pool ("butler events", 64);
|
||||
return ((Butler *) arg)->thread_work ();
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ using namespace PBD;
|
|||
using namespace ARDOUR;
|
||||
using namespace MIDI;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
void
|
||||
setup_enum_writer ()
|
||||
{
|
||||
|
@ -584,6 +586,8 @@ setup_enum_writer ()
|
|||
|
||||
}
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
||||
/* deserializing types from ardour/types.h */
|
||||
|
||||
std::istream& operator>>(std::istream& o, HeaderFormat& var)
|
||||
|
@ -795,3 +799,5 @@ std::ostream& operator<<(std::ostream& o, const WaveformShape& var)
|
|||
std::string s = enum_2_string (var);
|
||||
return o << s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ void *
|
|||
ExportChannelConfiguration::_write_files (void *arg)
|
||||
{
|
||||
notify_gui_about_thread_creation (pthread_self(), "Export post-processing");
|
||||
SessionEvent::create_per_thread_pool ("exporter events", 64);
|
||||
|
||||
// cc can be trated like 'this'
|
||||
WriterThread & cc (*((WriterThread *) arg));
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "ardour/rc_configuration.h"
|
||||
#include "ardour/runtime_functions.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/session_event.h"
|
||||
#include "ardour/source_factory.h"
|
||||
#include "ardour/utils.h"
|
||||
|
||||
|
@ -110,6 +111,8 @@ mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
|
|||
|
||||
sigc::signal<void,std::string> ARDOUR::BootMessage;
|
||||
|
||||
void ARDOUR::setup_enum_writer ();
|
||||
|
||||
int
|
||||
ARDOUR::setup_midi ()
|
||||
{
|
||||
|
@ -283,15 +286,16 @@ lotsa_files_please ()
|
|||
int
|
||||
ARDOUR::init (bool use_vst, bool try_optimization)
|
||||
{
|
||||
if (!Glib::thread_supported())
|
||||
if (!Glib::thread_supported()) {
|
||||
Glib::thread_init();
|
||||
|
||||
PBD::ID::init ();
|
||||
|
||||
extern void setup_enum_writer ();
|
||||
}
|
||||
|
||||
(void) bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
||||
PBD::ID::init ();
|
||||
SessionEvent::init_event_pool ();
|
||||
|
||||
|
||||
/* provide a state version for the few cases that need it and are not
|
||||
driven by reading state from disk (e.g. undo/redo)
|
||||
*/
|
||||
|
|
|
@ -37,7 +37,45 @@ using namespace std;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
MultiAllocSingleReleasePool SessionEvent::pool ("event", sizeof (SessionEvent), 512);
|
||||
PerThreadPool* SessionEvent::pool;
|
||||
|
||||
void
|
||||
SessionEvent::init_event_pool ()
|
||||
{
|
||||
pool = new PerThreadPool;
|
||||
}
|
||||
|
||||
void
|
||||
SessionEvent::create_per_thread_pool (const std::string& name, unsigned long nitems)
|
||||
{
|
||||
/* this is a per-thread call that simply creates a thread-private ptr to
|
||||
a CrossThreadPool for use by this thread whenever events are allocated/released
|
||||
from SessionEvent::pool()
|
||||
*/
|
||||
pool->create_per_thread_pool (name, sizeof (SessionEvent), nitems);
|
||||
}
|
||||
|
||||
void *
|
||||
SessionEvent::operator new (size_t)
|
||||
{
|
||||
CrossThreadPool* p = pool->per_thread_pool ();
|
||||
SessionEvent* ev = static_cast<SessionEvent*> (p->alloc ());
|
||||
ev->own_pool = p;
|
||||
return ev;
|
||||
}
|
||||
|
||||
void
|
||||
SessionEvent::operator delete (void *ptr, size_t /*size*/)
|
||||
{
|
||||
Pool* p = pool->per_thread_pool ();
|
||||
SessionEvent* ev = static_cast<SessionEvent*> (ptr);
|
||||
|
||||
if (p == ev->own_pool) {
|
||||
p->release (ptr);
|
||||
} else {
|
||||
ev->own_pool->push (ev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SessionEventManager::add_event (nframes64_t frame, SessionEvent::Type type, nframes64_t target_frame)
|
||||
|
|
|
@ -1094,6 +1094,7 @@ Session::midi_thread_work ()
|
|||
vector<MIDI::Port*> ports;
|
||||
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048);
|
||||
SessionEvent::create_per_thread_pool (X_("MIDI I/O"), 128);
|
||||
|
||||
memset (&rtparam, 0, sizeof (rtparam));
|
||||
rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
|
||||
|
|
|
@ -59,6 +59,7 @@ static void
|
|||
peak_thread_work ()
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), string ("peakbuilder-") + to_string (pthread_self(), std::dec));
|
||||
SessionEvent::create_per_thread_pool (X_("PeakFile Builder "), 64);
|
||||
|
||||
while (true) {
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ def build(bld):
|
|||
obj.includes = ['.', '../surfaces/control_protocol', '..']
|
||||
obj.name = 'libardour'
|
||||
obj.target = 'ardour'
|
||||
obj.uselib = 'GLIBMM AUBIO SIGCPP XML UUID JACK SNDFILE SAMPLERATE LRDF OSX'
|
||||
obj.uselib = 'GLIBMM GTHREAD AUBIO SIGCPP XML UUID JACK SNDFILE SAMPLERATE LRDF OSX'
|
||||
obj.uselib_local = 'libpbd libmidipp libevoral libvamphost libvampplugin libtaglib librubberband'
|
||||
obj.vnum = LIBARDOUR_LIB_VERSION
|
||||
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
|
||||
|
@ -324,7 +324,7 @@ def build(bld):
|
|||
test/testrunner.cpp
|
||||
'''.split()
|
||||
testobj.includes = obj.includes + ['../pbd/']
|
||||
testobj.uselib = 'CPPUNIT SIGCPP JACK GLIBMM SAMPLERATE XML LRDF'
|
||||
testobj.uselib = 'CPPUNIT SIGCPP JACK GLIBMM GTHREAD SAMPLERATE XML LRDF'
|
||||
testobj.uselib_local = 'libpbd libmidipp libardour'
|
||||
testobj.name = 'libardour-tests'
|
||||
testobj.target = 'run-tests'
|
||||
|
|
|
@ -38,9 +38,11 @@ class Pool
|
|||
|
||||
std::string name() const { return _name; }
|
||||
|
||||
private:
|
||||
RingBuffer<void*>* free_list;
|
||||
protected:
|
||||
RingBuffer<void*> free_list;
|
||||
std::string _name;
|
||||
|
||||
private:
|
||||
void *block;
|
||||
};
|
||||
|
||||
|
@ -71,4 +73,33 @@ class MultiAllocSingleReleasePool : public Pool
|
|||
Glib::Mutex* m_lock;
|
||||
};
|
||||
|
||||
class CrossThreadPool : public Pool
|
||||
{
|
||||
public:
|
||||
CrossThreadPool (std::string n, unsigned long isize, unsigned long nitems);
|
||||
|
||||
void* alloc ();
|
||||
void push (void *);
|
||||
|
||||
private:
|
||||
RingBuffer<void*> pending;
|
||||
};
|
||||
|
||||
class PerThreadPool
|
||||
{
|
||||
public:
|
||||
PerThreadPool ();
|
||||
|
||||
GPrivate* key() const { return _key; }
|
||||
|
||||
void create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems);
|
||||
CrossThreadPool* per_thread_pool ();
|
||||
|
||||
private:
|
||||
GPrivate* _key;
|
||||
std::string _name;
|
||||
unsigned long _item_size;
|
||||
unsigned long _nitems;
|
||||
};
|
||||
|
||||
#endif // __qm_pool_h__
|
||||
|
|
|
@ -30,11 +30,11 @@ using namespace std;
|
|||
using namespace PBD;
|
||||
|
||||
Pool::Pool (string n, unsigned long item_size, unsigned long nitems)
|
||||
: free_list (nitems)
|
||||
, _name (n)
|
||||
{
|
||||
_name = n;
|
||||
|
||||
free_list = new RingBuffer<void*> (nitems);
|
||||
|
||||
/* since some overloaded ::operator new() might use this,
|
||||
its important that we use a "lower level" allocator to
|
||||
get more space.
|
||||
|
@ -48,8 +48,7 @@ Pool::Pool (string n, unsigned long item_size, unsigned long nitems)
|
|||
ptrlist[i] = static_cast<void *> (static_cast<char*>(block) + (i * item_size));
|
||||
}
|
||||
|
||||
free_list->write (ptrlist, nitems);
|
||||
|
||||
free_list.write (ptrlist, nitems);
|
||||
free (ptrlist);
|
||||
}
|
||||
|
||||
|
@ -65,7 +64,7 @@ Pool::alloc ()
|
|||
|
||||
// cerr << _name << " pool " << " alloc, thread = " << pthread_name() << " space = " << free_list->read_space() << endl;
|
||||
|
||||
if (free_list->read (&ptr, 1) < 1) {
|
||||
if (free_list.read (&ptr, 1) < 1) {
|
||||
fatal << "CRITICAL: " << _name << " POOL OUT OF MEMORY - RECOMPILE WITH LARGER SIZE!!" << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
|
@ -77,7 +76,7 @@ Pool::alloc ()
|
|||
void
|
||||
Pool::release (void *ptr)
|
||||
{
|
||||
free_list->write (&ptr, 1);
|
||||
free_list.write (&ptr, 1);
|
||||
// cerr << _name << ": release, now has " << free_list->read_space() << endl;
|
||||
}
|
||||
|
||||
|
@ -144,3 +143,64 @@ SingleAllocMultiReleasePool::release (void* ptr)
|
|||
Pool::release (ptr);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
free_per_thread_pool (void* ptr)
|
||||
{
|
||||
cerr << "Deleting a per thread pool @ " << ptr << endl;
|
||||
Pool* pptr = static_cast<Pool*>(ptr);
|
||||
delete pptr;
|
||||
}
|
||||
|
||||
PerThreadPool::PerThreadPool ()
|
||||
{
|
||||
{
|
||||
/* for some reason this appears necessary to get glib's thread private stuff to work */
|
||||
GPrivate* key;
|
||||
key = g_private_new (NULL);
|
||||
}
|
||||
|
||||
_key = g_private_new (free_per_thread_pool);
|
||||
}
|
||||
|
||||
void
|
||||
PerThreadPool::create_per_thread_pool (string n, unsigned long isize, unsigned long nitems)
|
||||
{
|
||||
Pool* p = new CrossThreadPool (n, isize, nitems);
|
||||
g_private_set (_key, p);
|
||||
}
|
||||
|
||||
CrossThreadPool*
|
||||
PerThreadPool::per_thread_pool ()
|
||||
{
|
||||
CrossThreadPool* p = static_cast<CrossThreadPool*> (g_private_get (_key));
|
||||
if (!p) {
|
||||
fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_self() << endmsg;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
CrossThreadPool::CrossThreadPool (string n, unsigned long isize, unsigned long nitems)
|
||||
: Pool (n, isize, nitems)
|
||||
, pending (nitems)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void*
|
||||
CrossThreadPool::alloc ()
|
||||
{
|
||||
void* ptr;
|
||||
while (pending.read (&ptr, 1) == 1) {
|
||||
free_list.write (&ptr, 1);
|
||||
}
|
||||
return Pool::alloc ();
|
||||
}
|
||||
|
||||
void
|
||||
CrossThreadPool::push (void* t)
|
||||
{
|
||||
pending.write (&t, 1);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,11 @@ BasicUI::~BasicUI ()
|
|||
void
|
||||
BasicUI::register_thread (std::string name)
|
||||
{
|
||||
std::string pool_name = name;
|
||||
pool_name += " events";
|
||||
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), name);
|
||||
SessionEvent::create_per_thread_pool (pool_name, 64);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -42,7 +42,7 @@ bool MackieControlProtocol::probe()
|
|||
|
||||
void * MackieControlProtocol::monitor_work()
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Mackie"));
|
||||
register_thread (X_("MCU"));
|
||||
|
||||
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
|
|
|
@ -374,9 +374,8 @@ OSC::get_unix_server_url()
|
|||
void *
|
||||
OSC::_osc_receiver(void * arg)
|
||||
{
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("OSC"));
|
||||
|
||||
static_cast<OSC*> (arg)->osc_receiver();
|
||||
static_cast<OSC*>(arg)->register_thread (X_("OSC"));
|
||||
static_cast<OSC*>(arg)->osc_receiver();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
16
libs/surfaces/powermate/i18n.h
Normal file
16
libs/surfaces/powermate/i18n.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef __i18n_h__
|
||||
#define __i18n_h__
|
||||
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/convert.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define _(Text) dgettext (PACKAGE,Text)
|
||||
#define N_(Text) gettext_noop (Text)
|
||||
#define X_(Text) Text
|
||||
#define I18N(Array) PBD::internationalize (PACKAGE, Array)
|
||||
|
||||
#endif // __i18n_h__
|
|
@ -12,12 +12,14 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <i18n.h>
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/error.h>
|
||||
#include <glibmm.h>
|
||||
|
||||
#include "pbd/pthread_utils.h"
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "powermate.h"
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
@ -72,17 +74,18 @@ int open_powermate (const char *dev, int mode)
|
|||
|
||||
int find_powermate(int mode)
|
||||
{
|
||||
char devname[256];
|
||||
int i, r;
|
||||
|
||||
for(i=0; i<NUM_EVENT_DEVICES; i++){
|
||||
sprintf(devname, "/dev/input/event%d", i);
|
||||
r = open_powermate(devname, mode);
|
||||
if(r >= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return -1;
|
||||
char devname[256];
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < NUM_EVENT_DEVICES; i++) {
|
||||
sprintf (devname, "/dev/input/event%d", i);
|
||||
r = open_powermate (devname, mode);
|
||||
if (r >= 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PowermateControlProtocol::PowermateControlProtocol (Session& s)
|
||||
|
@ -126,7 +129,7 @@ PowermateControlProtocol::set_active (bool inActivate)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pthread_create (&mThread, 0, SerialThreadEntry, this) == 0) {
|
||||
if (pthread_create_and_store ("Powermate", &mThread, 0, SerialThreadEntry, this) == 0) {
|
||||
_active = true;
|
||||
} else {
|
||||
return -1;
|
||||
|
@ -163,6 +166,7 @@ PowermateControlProtocol::set_state (const XMLNode& /*node*/, int /*version*/)
|
|||
void*
|
||||
PowermateControlProtocol::SerialThreadEntry (void* arg)
|
||||
{
|
||||
static_cast<PowermateControlProtocol*>(arg)->register_thread ("Powermate");
|
||||
return static_cast<PowermateControlProtocol*>(arg)->SerialThread ();
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ TranzportControlProtocol::monitor_work ()
|
|||
bool first_time = true;
|
||||
uint8_t offline = 0;
|
||||
|
||||
PBD::notify_gui_about_thread_creation (pthread_self(), X_("Tranzport"));
|
||||
register_thread (X_("Tranzport"));
|
||||
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
rtpriority_set();
|
||||
|
|
|
@ -35,10 +35,10 @@ WiimoteControlProtocol::~WiimoteControlProtocol()
|
|||
if (wiimote_handle) {
|
||||
cwiid_close(wiimote_handle);
|
||||
}
|
||||
|
||||
std::cerr << "Wiimote: closed" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WiimoteControlProtocol::probe()
|
||||
{
|
||||
|
@ -166,11 +166,12 @@ WiimoteControlProtocol::update_led_state()
|
|||
}
|
||||
|
||||
void
|
||||
WiimoteControlProtocol::wiimote_main()
|
||||
WiimoteControlProtocol::_wiimote_main ()
|
||||
{
|
||||
bdaddr_t bdaddr;
|
||||
unsigned char rpt_mode = 0;
|
||||
register_thread("Wiimote Discovery and Callback Thread");
|
||||
|
||||
register_thread ("Wiimote");
|
||||
|
||||
wiimote_discovery:
|
||||
|
||||
|
@ -261,6 +262,7 @@ wiimote_discovery:
|
|||
|
||||
|
||||
std::cerr << "Wiimote: main thread stopped" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
1
wscript
1
wscript
|
@ -465,6 +465,7 @@ def configure(conf):
|
|||
define_name = 'HAVE_AUDIOUNITS', linkflags = [ '-framework', 'AudioUnit' ])
|
||||
|
||||
autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2')
|
||||
autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2')
|
||||
autowaf.check_pkg(conf, 'glibmm-2.4', uselib_store='GLIBMM', atleast_version='2.14.0')
|
||||
if sys.platform == 'darwin':
|
||||
sub_config_and_use(conf, 'libs/appleutility')
|
||||
|
|
Loading…
Reference in New Issue
Block a user