cross-thread handling of SessionEvent allocation/deallocation, with widespread conseq...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 4 Dec 2009 19:24:09 +0000 (19:24 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 4 Dec 2009 19:24:09 +0000 (19:24 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6283 d708f5d6-7413-0410-9779-e7cbd77b26cf

26 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_timefx.cc
gtk2_ardour/sfdb_ui.cc
libs/ardour/analyser.cc
libs/ardour/ardour/session_event.h
libs/ardour/audioengine.cc
libs/ardour/butler.cc
libs/ardour/enums.cc
libs/ardour/export_channel_configuration.cc
libs/ardour/globals.cc
libs/ardour/session_events.cc
libs/ardour/session_midi.cc
libs/ardour/source_factory.cc
libs/ardour/wscript
libs/pbd/pbd/pool.h
libs/pbd/pool.cc
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/mackie/mackie_control_protocol_poll.cc
libs/surfaces/osc/osc.cc
libs/surfaces/powermate/i18n.h [new file with mode: 0644]
libs/surfaces/powermate/powermate.cc
libs/surfaces/tranzport/init.cc
libs/surfaces/wiimote/wiimote.cc
wscript

index 50aea1c24c1655ad4c4b1b5aae946d86c9729c8f..0607a03e54ad6dfc2fe516c7e497cd89f38dfc7c 100644 (file)
@@ -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;
index 833d26168a30fc257320cb37c40ad010efbe0073..f8b6d7c141ca5294fc8a0ed04573402cb0d80562 100644 (file)
@@ -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 ();
index fe003d231c869c602608605ad79f49663572d2a4..3b60f3c903946fb436408809d4058d536b2031c6 100644 (file)
@@ -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 ();
 }
 
index de1883330b1520dd5663da05fd2708b759f3f8f5..b52121f9c528a78b940c211ab76dadefe578dde6 100644 (file)
@@ -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);
 
index 3328b7122511f38f92013f82a01036b6daa8f8df..aa8d7b77f2a24164e23731b26964e9d624bc12ee 100644 (file)
@@ -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>
index 2e68cfed8332cc3ad91746e6812fff00665c8464..8e2ec99f27f65739389603ed74754356f078d654 100644 (file)
@@ -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 ();
index 767c374988476b6c2fa419da9fa33b4c71f9cdc5..07c795257f554d3c2c0a2a9a439980e92d6d3549 100644 (file)
@@ -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;
index 2f344eb8ba75b31516a825d89991d8161259e0fb..b69b06c4dbe4eebc1e6ae5479d3a5fb2fc1d5717 100644 (file)
@@ -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());
 }
 
index 3d43c11e38403837e4eac127c8a8a2a3a9f3c25b..76a7fb2424fdf84fafae0df29dfc081508993304 100644 (file)
@@ -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 ();
 }
 
index aa7dda9e505c22ccb13f8ef420b5f4febe6f2892..0676973e53f375b4f84b2ed07bd4d8ef11cac31b 100644 (file)
@@ -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;
 }
+
+
index 47bbbd276cb5f7a233c84debf3fa3b67bc780879..047aadc671c55fbba4a58c12b74e870c1e6181d3 100644 (file)
@@ -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));
index 6e6ae9bf802a07164f4707c6ffe2dcb9cfe311d1..9953524c34b6ed17373725e451032d6018e9aecc 100644 (file)
@@ -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,14 +286,15 @@ 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 ();
+       (void) bindtextdomain(PACKAGE, LOCALEDIR);
 
-       extern void setup_enum_writer ();
+       PBD::ID::init ();
+       SessionEvent::init_event_pool ();
 
-       (void) bindtextdomain(PACKAGE, LOCALEDIR);
 
        /* provide a state version for the few cases that need it and are not
           driven by reading state from disk (e.g. undo/redo)
index 98620e269fcf1e4ee3ddbb3d610cba9181409ee4..8818436ed76081b01b77a0f47bdba0108a07b7aa 100644 (file)
@@ -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)
index b05cfc83a2b4327a7382eb868c739ca37a2cc463..fe332b71c266f22adb4410660b94c592132dbb1c 100644 (file)
@@ -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 */
index 6753a0738f57ce318938148b12e02d4e2843f4f3..b85f5b67a0ab6cbbf74f84fb985c0e968fae7c71 100644 (file)
@@ -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) {
 
index 22d86ffd3c4e5ca4dea8fbe17b2576d925f2d8ef..67998ff5fb35dd824c456d87c692ff9a2fa06c0f 100644 (file)
@@ -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'
index 66a87abf96784ecd42f0b4256a9270ded931a09a..e8ad780dc2a6052a115d4dabc5f1569358a7638f 100644 (file)
@@ -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__
index 2a9022542a76aef6ee051ed02f485b15dcd87ee2..af57871da98e2fb2dc1287af6e4ed67b45d9de11 100644 (file)
@@ -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);
+}
index af457fe5a4f437edb2fa091505e9373be9b8f27a..3d336adb47e5088c9d6fa33e2dbc63f348d7f98b 100644 (file)
@@ -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
index 867a7d784a27747d0450ee01516501743cbe85bd..f6171c7f0e7d0fcc8d99304800895a2dc52e891e 100644 (file)
@@ -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);
index d5a28a38ce4cec99db98de3c9cd7e91c4cab9b72..af067f65bcd95e602fc80d6846a29d4c06682f56 100644 (file)
@@ -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;
 }
 
diff --git a/libs/surfaces/powermate/i18n.h b/libs/surfaces/powermate/i18n.h
new file mode 100644 (file)
index 0000000..dcbbfcf
--- /dev/null
@@ -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__
index a32c4696aeec71d9577e90c609576ec81c3e1ef2..0cdfba6f3ae050e14b62693770c30a732f4923ee 100644 (file)
 #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 ();
 }
 
index 726cb60d49335083b3ddd45bf7a39e63fd92c962..910d37a5de3c54535b4c10518f3592471197adf8 100644 (file)
@@ -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();
index 8864a5019fa24d47fc8cb3a3f2d8e4aee0c19b06..867e1c38e4385ed07cfad5776508123da61a3585 100644 (file)
@@ -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;
 }
 
 
diff --git a/wscript b/wscript
index 1fce071465f2b046d2ac047c3c17ef401a3ac45f..729161ba93e8b98876e47b1e1b3ccb011753e0d4 100644 (file)
--- a/wscript
+++ b/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')