Browse Source

Add CarlaThread class

tags/1.9.4
falkTX 12 years ago
parent
commit
070c1340fe
1 changed files with 213 additions and 0 deletions
  1. +213
    -0
      source/utils/carla_utils.hpp

+ 213
- 0
source/utils/carla_utils.hpp View File

@@ -24,8 +24,11 @@
#include <cstdlib>
#include <cstring>

// #define CPP11_MUTEX

#ifdef CPP11_MUTEX
# include <mutex>
# include <thread>
#else
# include <pthread.h>
#endif
@@ -314,6 +317,216 @@ private:
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaMutex)
};

// -------------------------------------------------
// CarlaThread class

class CarlaThread
{
public:
CarlaThread()
: fStarted(false),
fFinished(false)
{
#ifdef CPP11_MUTEX
cthread = nullptr;
#else
_zero();
pthread_attr_init(&pthreadAttr);
pthread_attr_setdetachstate(&pthreadAttr, PTHREAD_CREATE_JOINABLE);
#endif
}

~CarlaThread()
{
CARLA_ASSERT(! isRunning());

if (isRunning())
terminate();

#ifdef CPP11_MUTEX
if (cthread != nullptr)
{
cthread->join();
delete cthread;
}
#else
if (pthreadId != 0)
pthread_join(pthreadId, nullptr);

pthread_attr_destroy(&pthreadAttr);
#endif
}

bool start()
{
CARLA_ASSERT(! isRunning());

if (isRunning())
return false;

fStarted = false;
fFinished = false;

#ifdef CPP11_MUTEX
CARLA_ASSERT(cthread == nullptr);

if (cthread != nullptr)
return false;

cthread = new std::thread(_cthreadRoutine, this);
CARLA_ASSERT(cthread->joinable());

return true;
#else
CARLA_ASSERT(pthreadId == 0);

if (pthreadId != 0)
return false;

return (pthread_create(&pthreadId, &pthreadAttr, _pthreadRoutine, this) == 0);
#endif
}

bool stop(const unsigned int timeout = 0)
{
CARLA_ASSERT(isRunning());

if (! isRunning())
return true;

#ifdef CPP11_MUTEX
if (cthread == nullptr)
return true;
#else
if (pthreadId == 0)
return true;
#endif

if (timeout == 0)
{
#ifdef CPP11_MUTEX
cthread->join();
#else
pthread_join(pthreadId, nullptr);
#endif
}
else
{
for (unsigned int i=0; i < timeout && ! fFinished; i++)
carla_msleep(1);
}

if (! fFinished)
return false;

#ifdef CPP11_MUTEX
delete cthread;
cthread = nullptr;
#else
_zero();
#endif

return true;
}

void terminate()
{
CARLA_ASSERT(isRunning());

if (fFinished)
return;

#ifdef CPP11_MUTEX
if (cthread == nullptr)
return;
#else
if (pthreadId == 0)
return;
#endif

#ifdef CPP11_MUTEX
cthread->detach();
//cthread->join();
delete cthread;
cthread = nullptr;
#else
pthread_detach(pthreadId);
//pthread_join(pthreadId, nullptr);
pthread_cancel(pthreadId);
_zero();
#endif

fFinished = true;
}

bool isRunning()
{
return (fStarted && ! fFinished);
}

void waitForStarted(const unsigned int timeout = 0) // ms
{
if (fStarted)
return;

if (timeout == 0)
{
while (! fStarted) {}
}
else
{
for (unsigned int i=0; i < timeout && ! fStarted; i++)
carla_msleep(1);
}
}

void waitForFinished()
{
waitForStarted();
stop(0);
}

protected:
virtual void run() = 0;

private:
bool fStarted;
bool fFinished;

void handleRoutine()
{
fStarted = true;
run();
fFinished = true;
}

#ifdef CPP11_MUTEX
std::thread* cthread;

static void _cthreadRoutine(CarlaThread* const _this_)
{
_this_->handleRoutine();
}
#else
pthread_t pthreadId;
pthread_attr_t pthreadAttr;

static void* _pthreadRoutine(void* const _this_)
{
((CarlaThread*)_this_)->handleRoutine();
pthread_exit(nullptr);
}

void _zero()
{
carla_zeroStruct<pthread_t>(pthreadId);
}
#endif

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaThread)
};

// -------------------------------------------------
// CarlaString class



Loading…
Cancel
Save