13
0

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:
Robin Gareus 2022-02-28 22:32:33 +01:00
parent 3280523e90
commit e515e73db6
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 83 additions and 0 deletions

View File

@ -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

View File

@ -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;
}