Commit 30f37baf authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

* Removed Thread::abort (calling pthread_cancel) and Thread::waitOn

  because pthread_cleanup_push/pop are not implemented for Windows
* Added ImageStatusCallback AllFrames and AsFastAsPossible rate policies
parent 3c3283da
Subproject commit 4818a6d2b9c3cce0a3b83ffd876d3b1dbaba7782
Subproject commit df8d04cc6a2d2a205fbfadc0057d45e8956859f7
......@@ -105,7 +105,6 @@ class LIMACORE_API Thread
virtual ~Thread();
virtual void start();
virtual void abort();
void join();
bool hasStarted();
......@@ -113,12 +112,10 @@ class LIMACORE_API Thread
protected:
virtual void threadFunction() = 0;
virtual bool waitOn(Cond& cond, double timeout = -1);
pthread_attr_t m_thread_attr;
private:
static void *staticThreadFunction(void *data);
static void staticWaitCleanup(void *data);
pthread_t m_thread;
bool m_started;
......
......@@ -223,10 +223,8 @@ Thread::Thread()
Thread::~Thread()
{
if (m_started) {
abort();
pthread_join(m_thread, NULL);
}
if (m_started)
join();
pthread_attr_destroy(&m_thread_attr);
}
......@@ -235,40 +233,20 @@ void Thread::start()
if (m_started)
throw LIMA_COM_EXC(Error, "Thread already started");
m_finished = false;
if (pthread_create(&m_thread, &m_thread_attr, staticThreadFunction, this) != 0)
throw LIMA_HW_EXC(Error, "Error creating thread");
m_started = true;
}
bool Thread::waitOn(Cond& cond, double timeout)
{
bool ret;
pthread_cleanup_push(staticWaitCleanup, &cond);
// assume no exception in wait: push/pop managed with exceptions
ret = cond.wait(timeout);
pthread_cleanup_pop(0);
return ret;
}
void Thread::staticWaitCleanup(void *data)
{
Cond *cond = (Cond *) data;
cond->release();
}
void Thread::join()
{
pthread_join(m_thread,NULL);
}
void Thread::abort()
{
if (!m_started)
throw LIMA_COM_EXC(Error, "Thread has not been started");
throw LIMA_COM_EXC(Error, "Thread not started or joined");
if (!m_finished)
pthread_cancel(m_thread);
pthread_join(m_thread, NULL);
m_started = false;
}
bool Thread::hasStarted()
......
......@@ -98,14 +98,23 @@ namespace lima
DEB_CLASS_NAMESPC(DebModControl,"Control::ImageStatusCallback",
"Control");
public:
enum {
RateAsFastAsPossible,
RateAllFrames,
};
ImageStatusCallback();
virtual ~ImageStatusCallback();
void setRatePolicy(int rate_policy);
void getRatePolicy(int& rate_policy);
protected:
virtual void imageStatusChanged(const ImageStatus& img_status) = 0;
private:
friend class CtControl;
void setImageStatusCallbackGen(CtControl *cb_gen);
CtControl *m_cb_gen;
int m_rate_policy;
};
enum ErrorCode {NoError,
......
......@@ -55,8 +55,16 @@ using namespace lima;
class ImageStatusCallback
{
public:
enum {
RateAsFastAsPossible,
RateAllFrames,
};
ImageStatusCallback();
virtual ~ImageStatusCallback();
void setRatePolicy(int rate_policy);
void getRatePolicy(int& rate_policy);
protected:
virtual void imageStatusChanged(const CtControl::ImageStatus& status)=0;
};
......
......@@ -175,7 +175,7 @@ private:
Cond& m_cond;
ImageStatusCallback *m_cb;
ImageStatus m_last_status;
std::list<ChangeEvent *> m_event_list;
std::list<ChangeEvent *> m_event_list;
};
CtControl::ImageStatusThread::ImageStatusThread(Cond& cond,
......@@ -188,7 +188,7 @@ CtControl::ImageStatusThread::ImageStatusThread(Cond& cond,
start();
// wait thread is ready
waitOn(m_cond);
m_cond.wait();
}
CtControl::ImageStatusThread::~ImageStatusThread()
......@@ -196,8 +196,12 @@ CtControl::ImageStatusThread::~ImageStatusThread()
DEB_DESTRUCTOR();
AutoMutex lock(m_cond.mutex());
// signal quit
m_event_list.push_front(NULL);
m_cond.broadcast();
while (!m_event_list.empty())
waitOn(m_cond);
m_cond.wait();
}
void CtControl::ImageStatusThread::imageStatusChanged(const ImageStatus& status,
......@@ -211,6 +215,10 @@ void CtControl::ImageStatusThread::imageStatusChanged(const ImageStatus& status,
AutoMutex lock(m_cond.mutex());
int cb_rate_policy;
m_cb->getRatePolicy(cb_rate_policy);
if (cb_rate_policy == ImageStatusCallback::RateAllFrames)
force = true;
if ((status == m_last_status) || ((status < m_last_status) && !force)) {
DEB_TRACE() << "Skipping";
return;
......@@ -238,7 +246,7 @@ void CtControl::ImageStatusThread::imageStatusChanged(const ImageStatus& status,
m_cond.broadcast();
while (wait && !finished)
waitOn(m_cond);
m_cond.wait();
}
void CtControl::ImageStatusThread::threadFunction()
......@@ -252,11 +260,14 @@ void CtControl::ImageStatusThread::threadFunction()
while (true) {
while (m_event_list.empty())
waitOn(m_cond);
m_cond.wait();
ChangeEvent *event = m_event_list.back();
m_event_list.pop_back();
if (!event)
break;
lock.unlock();
DEB_TRACE() << "Calling callback: " << DEB_VAR1(event->status);
m_cb->imageStatusChanged(event->status);
......@@ -269,6 +280,8 @@ void CtControl::ImageStatusThread::threadFunction()
delete event;
}
m_cond.broadcast();
}
......@@ -1161,7 +1174,7 @@ void CtControl::Status::reset()
// class ImageStatus
// ----------------------------------------------------------------------------
CtControl::ImageStatusCallback::ImageStatusCallback()
: m_cb_gen(NULL)
: m_cb_gen(NULL), m_rate_policy(RateAsFastAsPossible)
{
DEB_CONSTRUCTOR();
}
......@@ -1180,6 +1193,22 @@ CtControl::ImageStatusCallback::setImageStatusCallbackGen(CtControl *cb_gen)
m_cb_gen = cb_gen;
}
void
CtControl::ImageStatusCallback::setRatePolicy(int rate_policy)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(rate_policy);
m_rate_policy = rate_policy;
}
void
CtControl::ImageStatusCallback::getRatePolicy(int& rate_policy)
{
DEB_MEMBER_FUNCT();
rate_policy = m_rate_policy;
DEB_RETURN() << DEB_VAR1(rate_policy);
}
#ifdef WIN32
CtAcquisition* CtControl::acquisition() { return m_ct_acq; }
CtSaving* CtControl::saving() { return m_ct_saving; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment