Implement a replacement for Glib::Threads::Thread
This is mainly because Glib::Threads (g_system_thread_new) uses pthread on Un*x, but on Windows relies on GThreadWin32 (HANDLE)_beginthreadex This later causes issues e.g. in BaseUI::run() ``` unhandled exception (type Glib::Error) in signal handler: domain: g_thread_error code : 0 what : Error setting new thread priority: The parameter is incorrect. ```
This commit is contained in:
parent
3280523e90
commit
e515e73db6
@ -93,6 +93,26 @@ LIBPBD_API bool pbd_mach_set_realtime_policy (pthread_t thread_id, double period
|
||||
namespace PBD {
|
||||
LIBPBD_API extern void notify_event_loops_about_thread_creation (pthread_t, const std::string&, int requests = 256);
|
||||
LIBPBD_API extern PBD::Signal3<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
|
||||
|
||||
class LIBPBD_API Thread {
|
||||
public:
|
||||
static Thread* create (boost::function<void ()> const&, std::string const& name = "");
|
||||
static Thread* self ();
|
||||
void join ();
|
||||
bool caller_is_self () const;
|
||||
|
||||
private:
|
||||
Thread ();
|
||||
Thread (boost::function<void ()> const&, std::string const& name = "");
|
||||
Thread (Thread const&); /* precent copy-construction */
|
||||
|
||||
static void* _run (void*);
|
||||
|
||||
pthread_t _t;
|
||||
std::string _name;
|
||||
boost::function<void ()> _slot;
|
||||
bool _joinable;
|
||||
};
|
||||
}
|
||||
|
||||
/* pthread-w32 does not support realtime scheduling
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/pthread_utils.h"
|
||||
|
||||
#ifdef COMPILER_MSVC
|
||||
@ -436,3 +437,65 @@ pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns, bool main)
|
||||
#endif
|
||||
return false; // OK
|
||||
}
|
||||
|
||||
PBD::Thread*
|
||||
PBD::Thread::create (boost::function<void ()> const& slot, std::string const& name)
|
||||
{
|
||||
try {
|
||||
return new PBD::Thread (slot, name);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PBD::Thread*
|
||||
PBD::Thread::self ()
|
||||
{
|
||||
return new PBD::Thread ();
|
||||
}
|
||||
|
||||
PBD::Thread::Thread ()
|
||||
: _name ("Main")
|
||||
, _joinable (false)
|
||||
{
|
||||
_t = pthread_self ();
|
||||
}
|
||||
|
||||
PBD::Thread::Thread (boost::function<void ()> const& slot, std::string const& name)
|
||||
: _name (name)
|
||||
, _slot (slot)
|
||||
, _joinable (true)
|
||||
{
|
||||
pthread_attr_t thread_attributes;
|
||||
pthread_attr_init (&thread_attributes);
|
||||
|
||||
if (pthread_create (&_t, &thread_attributes, _run, this)) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
PBD::Thread::_run (void* arg) {
|
||||
PBD::Thread* self = static_cast<PBD::Thread *>(arg);
|
||||
if (!self->_name.empty ()) {
|
||||
pthread_set_name (self->_name.c_str ());
|
||||
}
|
||||
self->_slot ();
|
||||
|
||||
pthread_exit (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PBD::Thread::join ()
|
||||
{
|
||||
if (_joinable) {
|
||||
pthread_join (_t, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PBD::Thread::caller_is_self () const
|
||||
{
|
||||
return pthread_equal (_t, pthread_self ()) != 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user