git-svn-id: svn://db.shs.com.ru/pip@756 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-02-18 18:30:51 +00:00
parent 0af7eabf56
commit 217947cc89
16 changed files with 296 additions and 217 deletions

View File

@@ -1,44 +1,29 @@
#include "pip.h"
class A: public PIObject {
PIOBJECT(A)
class Base: public PIObject {
PIOBJECT(Base)
public:
A() {}
EVENT_HANDLER1(void, handlerA1, float, f) {piCout << "handlerA1 f" << f;}
EVENT_HANDLER1(void, handlerA2, PIString, s) {piCout << "handlerA2 s" << s;}
//uchar _[0x10];
};
class B: public PIObject {
PIOBJECT(B)
public:
B() {}
EVENT1(eventB1, float, f)
EVENT1(eventB2, PIString, s)
//uchar _[0x20];
EVENT_HANDLER(void, tick) {piCout << "tick";}
};
int main() {
A a;
B b;
CONNECTU(&b, eventB1, &a, handlerA1)
CONNECTU(&b, eventB2, &a, handlerA2)
a.dump();
WAIT_FOREVER
b.dump();
b.eventB1(0.33);
b.eventB2("str");
/*PIByteArray msg = PIByteArray::fromHex("0110f0f00001020001");
PIByteArray src = PIByteArray::fromHex("836f");
ushort s; memcpy(&s, src.data(), 2);
//CRC_16 crc = standardCRC_16();
CRC_16 crc = CRC_16(0x8005, 0xFFFF, 0xFFFF, false);
piCout << PICoutManipulators::Hex << s;
piCout << PICoutManipulators::Hex << crc.calculate(msg);*/
//PIIODevice * ser = PIIODevice::createFromFullPath("ser://COM3:9600:7:e:1 (wo,bwr)");
//piCout << ser << ser->constructVariant() << ser->constructFullPath();
//ser = PIIODevice::createFromVariant(ser->constructVariant());
//piCout << ser << ser->constructVariant() << ser->constructFullPath();
Base b;
PIConnection c;
c.configureFromConfig("d:/orders/nicirt/bin/spec_core.conf", "core");
//CONNECTU(&t, tickEvent, &b, tick);
piCout << "start ...";
c.start();
//t.start(500);
piSleep(3);
//t.stop();
//delete t;
c.stop();
piCout << "deleted";
/*PIEthernet * eth = PIIODevice::createFromFullPath("eth://UDP:::192.168.0.33:16666")->cast<PIEthernet>();
for (;;) {
eth->send(PIByteArray::fromHex("00112233445566778899"));
piSleep(1.5);
}*/
return 0;
}

View File

@@ -104,6 +104,7 @@ PIConsole::PIConsole(bool startNow, PIKbdListener::KBFunc slot): PIThread() {
addTab("main");
listener = new PIKbdListener(key_event, this);
peer_timer = new PITimer();
peer_timer->setName("__S__.PIConsole.peer_timer");
peer = 0;
server_mode = pause_ = false;
state = Disconnected;

View File

@@ -216,6 +216,9 @@
#define PRIVATE (__privateinitializer__.p)
#define PRIVATEWB __privateinitializer__.p
#define NO_COPY_CLASS(name) \
explicit name(const name & ); \
void operator =(const name & );
#ifdef FREERTOS
# define PIP_MIN_MSLEEP 10.

View File

@@ -136,7 +136,8 @@ PICout::~PICout() {
if (fc_) applyFormat(PICoutManipulators::Default);
if (cc_) return;
newLine();
PICout::__mutex__().unlock();
if ((co_ & NoLock) != NoLock)
PICout::__mutex__().unlock();
if (buffer_)
((NotifierObject*)Notifier::object())->finished(id_, buffer_);
}
@@ -427,7 +428,8 @@ void PICout::init() {
#endif
buffer_ = 0;
id_ = 0;
PICout::__mutex__().lock();
if ((co_ & NoLock) != NoLock)
PICout::__mutex__().lock();
}

View File

@@ -68,11 +68,13 @@ namespace PICoutManipulators {
//! \brief Enum contains control of PICout
enum PIP_EXPORT PICoutControl {
AddNone /*! No controls */ = 0x0,
AddSpaces /*! Spaces will be appear after each output */ = 0x1,
AddNewLine /*! New line will be appear after all output */ = 0x2,
AddQuotes /*! Each string will be quoted */ = 0x4,
AddAll /*! All controls */ = 0xFFFFFFFF
AddNone /*! No controls */ = 0x0,
AddSpaces /*! Spaces will be appear after each output */ = 0x1,
AddNewLine /*! New line will be appear after all output */ = 0x2,
AddQuotes /*! Each string will be quoted */ = 0x4,
DefaultControls /*! Default controls */ = AddSpaces | AddNewLine,
AddAll /*! All controls */ = 0xFF,
NoLock /*! Don`t use mutex for output */ = 0x100,
};
//! \brief Enum contains output format
@@ -113,7 +115,7 @@ namespace PICoutManipulators {
class PIP_EXPORT PICout {
public:
//! Default constructor with default features (AddSpaces and AddNewLine)
explicit PICout(PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine);
explicit PICout(PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::DefaultControls);
//! Construct with external buffer and id "id". See \a Notifier for details
PICout(PIString * buffer, int id = 0, PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine);

View File

@@ -191,8 +191,8 @@ void PIIODevice::_init() {
#else
setThreadedReadBufferSize(4096);
#endif
timer.setName("__S__reopen_timer");
write_thread.setName("__S__write_thread");
timer.setName("__S__.PIIODevice.reopen_timer");
write_thread.setName("__S__.PIIODevice.write_thread");
CONNECT2(void, void * , int, &timer, tickEvent, this, check_start);
CONNECT(void, &write_thread, started, this, write_func);
}

View File

@@ -391,6 +391,8 @@ protected:
void * ret_data_;
private:
NO_COPY_CLASS(PIIODevice)
EVENT_HANDLER2(void, check_start, void * , data, int, delim);
EVENT_HANDLER(void, write_func);
@@ -401,8 +403,6 @@ private:
void run();
void end() {terminate();}
static void cacheFullPath(const PIString & full_path, const PIIODevice * d);
explicit PIIODevice(const PIIODevice & );
void operator =(const PIIODevice & );
PITimer timer;
PITimeMeasurer tm;

View File

@@ -159,6 +159,7 @@ PIEthernet::Address PIPeer::PeerInfo::fastestAddress() const {
REGISTER_DEVICE(PIPeer)
PIPeer::PIPeer(const PIString & n): PIIODevice(), inited__(false), eth_tcp_srv(PIEthernet::TCP_Server), eth_tcp_cli(PIEthernet::TCP_Client), diag_s(false), diag_d(false) {
sync_timer.setName("__S__.PIPeer.sync_timer");
//piCout << " PIPeer" << uint(this);
destroyed = false;
setDebug(false);

View File

@@ -1210,6 +1210,14 @@ PIConnection::Extractor::~Extractor() {
}
PIConnection::Sender::Sender(PIConnection * parent_): parent(parent_), int_(0.f) {
setName("__S__.PIConnection.Sender");
needLockRun(true);
}
void PIConnection::Sender::tick(void * , int) {
if (parent == 0) return;
PIByteArray data;
@@ -1225,6 +1233,8 @@ void PIConnection::Sender::tick(void * , int) {
}
void PIConnection::unboundExtractor(PIPacketExtractor * pe) {
if (pe == 0) return;
channels_.remove(pe);

View File

@@ -383,7 +383,7 @@ private:
class PIP_EXPORT Sender: public PITimer {
PIOBJECT_SUBCLASS(Sender, PIObject)
public:
Sender(PIConnection * parent_ = 0): parent(parent_), int_(0.f) {needLockRun(true);}
Sender(PIConnection * parent_ = 0);
~Sender() {stop();}
PIConnection * parent;
PIVector<PIIODevice * > devices;

View File

@@ -206,6 +206,8 @@ public:
//! \}
private:
NO_COPY_CLASS(PIDiagnostics)
struct Entry {
Entry() {bytes_ok = bytes_fail = 0; cnt_ok = cnt_fail = 0; empty = true;}
ullong bytes_ok;

View File

@@ -53,8 +53,7 @@ public:
bool isLocked() const;
private:
explicit PIMutex(const PIMutex & );
void operator =(const PIMutex & );
NO_COPY_CLASS(PIMutex)
void init();
void destroy();

View File

@@ -34,8 +34,8 @@
#if defined(MAC_OS) || defined(BLACKBERRY) || defined(FREERTOS)
# include <pthread.h>
#endif
__THREAD_FUNC_RET__ thread_function(void * t) {PIThread::__thread_func__(t); return 0;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {PIThread::__thread_func_once__(t); return 0;}
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return 0;}
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return 0;}
#define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
#define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
@@ -128,18 +128,18 @@ __PIThreadCollection * __PIThreadCollection_Initializer__::__instance__(0);
__PIThreadCollection_Initializer__::__PIThreadCollection_Initializer__() {
count_++;
//piCout << "try create Core" << count_;
//PICout(PICoutManipulators::DefaultControls) << "try create Core" << count_;
if (count_ > 1) return;
//piCout << "create Core";
//PICout(PICoutManipulators::DefaultControls) << "create Core";
__instance__ = new __PIThreadCollection();
}
__PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
count_--;
//piCout << "try delete Core" << count_;
//PICout(PICoutManipulators::DefaultControls) << "try delete Core" << count_;
if (count_ > 0) return;
//piCout << "delete Core";
//PICout(PICoutManipulators::DefaultControls) << "delete Core";
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
@@ -168,7 +168,6 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay)
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
piCout << "PIThread" << this;
if (startNow) start(timer_delay);
}
@@ -181,7 +180,6 @@ PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
terminating = running_ = lockRun = false;
priority_ = piNormal;
delay_ = timer_delay;
piCout << "PIThread" << this;
if (startNow) start(timer_delay);
}
@@ -191,11 +189,11 @@ PIThread::~PIThread() {
if (!running_ || PRIVATE->thread == 0) return;
#ifdef FREERTOS
//void * ret(0);
//piCout << "~PIThread" << PRIVATE->thread;
//piCout << pthread_join(PRIVATE->thread, 0);
piCout << "FreeRTOS can't terminate pthreads! waiting for stop";
//PICout(PICoutManipulators::DefaultControls) << "~PIThread" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << pthread_join(PRIVATE->thread, 0);
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true);
//piCout << "stopped!";
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
#ifndef WINDOWS
# ifdef ANDROID
@@ -204,8 +202,6 @@ PIThread::~PIThread() {
pthread_cancel(PRIVATE->thread);
# endif
# else
piCout << "terminate by ~PIThread" << this;
while(1) msleep(10);
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
# endif
@@ -214,6 +210,13 @@ PIThread::~PIThread() {
}
void PIThread::stop(bool wait) {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop ..." << running_ << wait;
terminating = true;
if (wait) waitForFinish();
}
bool PIThread::start(int timer_delay) {
if (running_) return false;
//if (terminating) waitForFinish();
@@ -228,7 +231,7 @@ bool PIThread::start(int timer_delay) {
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&PRIVATE->thread, &attr, thread_function, this);
//piCout << "pthread_create" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
# ifdef MAC_OS
@@ -272,7 +275,7 @@ bool PIThread::startOnce() {
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&(PRIVATE->thread), &attr, thread_function_once, this);
//piCout << "pthread_create" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
# ifdef MAC_OS
@@ -304,17 +307,18 @@ bool PIThread::startOnce() {
void PIThread::terminate() {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_;
#ifdef FREERTOS
piCout << "FreeRTOS can't terminate pthreads! waiting for stop";
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true);
//piCout << "stopped!";
//PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
if (PRIVATE->thread == 0) return;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
terminating = running_ = false;
tid_ = -1;
//piCout << "terminate" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
#ifndef WINDOWS
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
@@ -325,16 +329,13 @@ void PIThread::terminate() {
//pthread_join(PRIVATE->thread, &ret);
# endif
#else
piCout << "terminate by terminate";
while (1) {
msleep(10);
}
TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread);
#endif
PRIVATE->thread = 0;
end();
#endif
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
}
@@ -372,7 +373,7 @@ void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
#ifndef WINDOWS
if (!running_ || (PRIVATE->thread == 0)) return;
//piCout << "setPriority" << PRIVATE->thread;
//PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
policy_ = 0;
memset(&(PRIVATE->sparam), 0, sizeof(PRIVATE->sparam));
pthread_getschedparam(PRIVATE->thread, &policy_, &(PRIVATE->sparam));
@@ -393,6 +394,7 @@ void PIThread::setPriority(PIThread::Priority prior) {
bool PIThread::waitForFinish(int timeout_msecs) {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "PIThread::waitForFinish" << running_ << terminating << timeout_msecs;
if (!running_) return true;
if (timeout_msecs < 0) {
while (running_)
@@ -420,7 +422,7 @@ bool PIThread::waitForStart(int timeout_msecs) {
}
void PIThread::__thread_func__(void * t) {
void PIThread::__thread_func__() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
@@ -429,61 +431,74 @@ void PIThread::__thread_func__(void * t) {
#else
//__PISetTimerResolution();
#endif
PIThread & ct = *((PIThread * )t);
#ifdef WINDOWS
ct.tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
ct.tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
if (ct.lockRun) ct.mutex_.lock();
ct.begin();
if (ct.lockRun) ct.mutex_.unlock();
ct.started();
while (!ct.terminating) {
ct.maybeCallQueuedEvents();
if (ct.lockRun) ct.mutex_.lock();
// piCout << "thread" << ct.name() << "..." << ct.lockRun;
ct.run();
//printf("thread %p tick\n", &ct);
if (ct.ret_func != 0) ct.ret_func(ct.data_);
if (ct.lockRun) ct.mutex_.unlock();
// piCout << "thread" << ct.name() << "done";
if (ct.delay_ > 0) {
ct.tmr_.reset();
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
REGISTER_THREAD(this);
running_ = true;
if (lockRun) mutex_.lock();
begin();
if (lockRun) mutex_.unlock();
started();
while (!terminating) {
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) mutex_.lock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
run();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
//printf("thread %p tick\n", this);
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
if (ret_func != 0) ret_func(data_);
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
if (lockRun) mutex_.unlock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(ct.delay_ - ct.tmr_.elapsed_m(), PIP_MIN_MSLEEP);
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
#ifdef WINDOWS
/*if (sl <= 1. && sl >= 0.) {
piMSleep(PIP_MIN_MSLEEP);
continue;
}*/
#endif
//printf("%f %f %f\n", double(ct.delay_), ct.tmr_.elapsed_m(), sl);
if (ct.terminating) break;
//printf("%f %f %f\n", double(delay_), tmr_.elapsed_m(), sl);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
ct.stopped();
if (ct.lockRun) ct.mutex_.lock();
ct.end();
if (ct.lockRun) ct.mutex_.unlock();
ct.terminating = ct.running_ = false;
ct.tid_ = -1;
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) mutex_.lock();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) mutex_.unlock();
terminating = running_ = false;
tid_ = -1;
PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
piCout << "pthread_exit" << &ct;
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);
(ct.__privateinitializer__.p)->thread = 0;
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);
@@ -497,7 +512,7 @@ void PIThread::__thread_func__(void * t) {
}
void PIThread::__thread_func_once__(void * t) {
void PIThread::__thread_func_once__() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
@@ -506,33 +521,32 @@ void PIThread::__thread_func_once__(void * t) {
#else
//__PISetTimerResolution();
#endif
PIThread & ct = *((PIThread * )t);
#ifdef WINDOWS
ct.tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
ct.tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name());
REGISTER_THREAD(&ct);
ct.running_ = true;
ct.begin();
ct.started();
if (ct.lockRun) ct.mutex_.lock();
ct.run();
if (ct.ret_func != 0) ct.ret_func(ct.data_);
if (ct.lockRun) ct.mutex_.unlock();
ct.stopped();
ct.end();
ct.terminating = ct.running_ = false;
ct.tid_ = -1;
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
REGISTER_THREAD(this);
running_ = true;
begin();
started();
if (lockRun) mutex_.lock();
run();
if (ret_func != 0) ret_func(data_);
if (lockRun) mutex_.unlock();
stopped();
end();
terminating = running_ = false;
tid_ = -1;
//cout << "thread " << t << " exiting ... " << endl;
//piCout << "pthread_exit" << (ct.__privateinitializer__.p)->thread;
UNREGISTER_THREAD(&ct);
PIINTROSPECTION_UNREGISTER_THREAD(ct.tid());
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
#ifndef WINDOWS
pthread_detach((ct.__privateinitializer__.p)->thread);
(ct.__privateinitializer__.p)->thread = 0;
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);

View File

@@ -82,12 +82,12 @@ public:
EVENT_HANDLER0(bool, start) {return start(-1);}
EVENT_HANDLER1(bool, start, int, timer_delay);
bool start(ThreadFunc func) {ret_func = func; return start(-1);}
bool start(ThreadFunc func) {return start(func, -1);}
bool start(ThreadFunc func, int timer_delay) {ret_func = func; return start(timer_delay);}
EVENT_HANDLER0(bool, startOnce);
EVENT_HANDLER1(bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();}
EVENT_HANDLER0(void, stop) {stop(false);}
EVENT_HANDLER1(void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();}
EVENT_HANDLER1(void, stop, bool, wait);
EVENT_HANDLER0(void, terminate);
//! \brief Set common data passed to external function
@@ -126,8 +126,8 @@ public:
//! \brief Returns thread ID
llong tid() const {return tid_;}
static void __thread_func__(void*);
static void __thread_func_once__(void*);
void __thread_func__();
void __thread_func_once__();
EVENT(started)
EVENT(stopped)
@@ -221,6 +221,10 @@ protected:
PIThread::Priority priority_;
ThreadFunc ret_func;
PRIVATE_DECLARATION
private:
NO_COPY_CLASS(PIThread)
};

View File

@@ -18,7 +18,7 @@
*/
#include "pitimer.h"
#include <stdio.h>
#include "piincludes_p.h"
#ifdef PIP_TIMER_RT
# include <csignal>
#endif
@@ -73,6 +73,7 @@ bool _PITimerBase::start(double interval_ms) {
if (isRunning()) stop(true);
deferred_ = false;
setInterval(interval_ms);
piCout << "_PITimerBase::startTimer"<<interval_ms<<"...";
running_ = startTimer(interval_ms);
return running_;
}
@@ -99,15 +100,16 @@ void _PITimerBase::startDeferred(double interval_ms, double delay_ms) {
bool _PITimerBase::stop(bool wait) {
piCout << "_PITimerBase::stop" << isRunning();
//piCout << GetCurrentThreadId() << "_PITimerBase::stop" << wait << isRunning();
if (!isRunning()) return true;
piCout << "_PITimerBase::stopTimer";
piCout << "_PITimerBase::stopTimer ...";
running_ = !stopTimer(wait);
return !running_;
}
class _PITimerImp_Thread: public _PITimerBase {
public:
_PITimerImp_Thread();
@@ -147,7 +149,7 @@ private:
class _PITimerImp_Pool: public _PITimerImp_Thread {
public:
_PITimerImp_Pool();
virtual ~_PITimerImp_Pool() {}
virtual ~_PITimerImp_Pool() {stop(true);}
private:
class Pool: public PIThread {
public:
@@ -172,14 +174,13 @@ _PITimerImp_Thread::_PITimerImp_Thread() {
wait_dt = 100;
wait_dd = 200;
wait_tick = 10;
piCout << "new _PITimerImp_Thread" << &thread_ << this;
piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
//piCout << "new _PITimerImp_Thread";
}
_PITimerImp_Thread::~_PITimerImp_Thread() {
piCout << "~_PITimerImp_Thread ..." << &thread_ << this;
thread_.stop(true);
piCout << "~_PITimerImp_Thread done" << &thread_ << this;
stop(true);
}
@@ -209,7 +210,6 @@ bool _PITimerImp_Thread::startTimer(double interval_ms) {
bool _PITimerImp_Thread::stopTimer(bool wait) {
piCout << "stop timer..." << &thread_ << this;
#ifndef FREERTOS
thread_.stop(true);
#else
@@ -219,19 +219,12 @@ bool _PITimerImp_Thread::stopTimer(bool wait) {
if (thread_.isRunning())
thread_.terminate();
#endif
piCout << "stop timer done!" << this << st_wait;
return true;
}
bool _PITimerImp_Thread::threadFunc() {
//piCout << "threadFunc";
//printf("threadFunc\n");
if (!running_) {
//piCout << "threadFunc 1";
//printf("threadFunc 1");
return false;
}
if (!running_) return false;
if (deferred_) {
PISystemTime dwt;
int wth(wait_dt);
@@ -242,69 +235,46 @@ bool _PITimerImp_Thread::threadFunc() {
dwt = st_time - PISystemTime::current(true);
if (wth > 0) {
if (dwt.toMilliseconds() > wth + 1.) {
//printf("wait 2\n");
//piCout << "wait 2" << this << dwt;
msleep(wth);
//printf("threadFunc 2\n");
//piCout << "threadFunc 2";
piMSleep(wth);
return false;
} else {
//piCout << "wait 3" << this << dwt;
//printf("wait 3\n");
dwt.sleep();
deferred_ = false;
st_time = PISystemTime::current(true);
}
} else {
if (dwt.toMilliseconds() > 0.1) {
//piCout << "threadFunc 3";
//printf("threadFunc 3\n");
if (dwt.toMilliseconds() > 0.1)
return false;
}
}
}
st_wait = st_time - PISystemTime::current(true);
//piCout << "wait" << this << st_wait;
if (st_wait.abs() > st_odt || st_wait.seconds <= -5) {
piCout << &thread_ << "adjust" << "...";
adjustTimes();
//piCout << "threadFunc 4";
//printf("threadFunc 4\n");
piCout << &thread_ << "adjust" << "ok";
return true;
}
if (wait_tick > 0) {
if (st_wait.toMilliseconds() > wait_tick + 1.) {
//piCout << "wait 5" << this << wait_tick;
//printf("wait 5 %d\n", wait_tick);
//fflush(stdout);
msleep(wait_tick);
//piCout << "threadFunc 5";
//printf("threadFunc 5\n");
//fflush(stdout);
piMSleep(wait_tick);
return false;
} else {
//piCout << "wait 6" << this << st_wait;
//printf("wait 6 %f\n" , st_wait.toMicroseconds());
piCout << &thread_ << "sleep for" << st_wait;
st_wait.sleep();
}
} else {
if (st_wait.toMilliseconds() > 0.1) {
//piCout << "threadFunc 6";
//printf("threadFunc 6\n");
if (st_wait.toMilliseconds() > 0.1)
return false;
}
}
st_time += st_inc;
if (!parent->isPIObject()) {
piCout << "Achtung! PITimer \"parent\" is not PIObject!";
//piCout << "threadFunc 7";
printf("threadFunc 7\n");
return false;
}
//piCout << "timer tick";
//printf("timer tick\n");
piCout << &thread_ << "tfunc" << "...";
tfunc(parent);
//piCout << "threadFunc 8";
//printf("threadFunc 8\n");
piCout << &thread_ << "tfunc" << "ok";
return true;
}
@@ -529,18 +499,42 @@ PITimer::~PITimer() {
}
double PITimer::interval() const {
init();
return imp->interval_;
}
void PITimer::setInterval(double ms) {
init();
setProperty("interval", ms);
imp->setInterval(ms);
}
bool PITimer::isRunning() const {
init();
return imp->running_;
}
bool PITimer::isStopped() const {
init();
return !imp->running_;
}
void PITimer::initFirst() {
setProperty("interval", 0.);
lockRun = false;
data_t = 0;
ret_func = 0;
imp = 0;
init();
setProperty("interval", 0.);
}
void PITimer::init() {
destroy();
void PITimer::init() const {
if (imp) return;
switch (imp_mode) {
case PITimer::Pool: imp = new _PITimerImp_Pool(); break;
case PITimer::ThreadRT:
@@ -553,16 +547,17 @@ void PITimer::init() {
case PITimer::Thread: imp = new _PITimerImp_Thread(); break;
default: piCout << "Fatal: invalid implementation() of" << this << "!"; assert(0);
}
if (imp == 0) return;
if (!imp) return;
piCout << this << "init" << imp;
imp->tfunc = tickImpS;
imp->parent = this;
imp->parent = const_cast<PITimer*>(this);
}
void PITimer::destroy() {
//piCout << "destroy" << this << imp;
if (imp == 0) return;
imp->stop(true); ///BUG: WTF FreeRTOS segfault on this!
if (!imp) return;
piCout << this << "destroy" << imp;
imp->stop(false); ///BUG: WTF FreeRTOS segfault on this!
delete imp;
imp = 0;
}
@@ -571,15 +566,15 @@ void PITimer::destroy() {
void PITimer::tickImp() {
if (!isRunning()) return;
if (lockRun) lock();
if (ret_func != 0) ret_func(data_t, 1);
if (ret_func) ret_func(data_t, 1);
tick(data_t, 1);
tickEvent(data_t, 1);
maybeCallQueuedEvents();
piForeach (Delimiter & i, delims) {
if (i.delim > ++(i.tick)) continue;
i.tick = 0;
if (i.slot != 0) i.slot(data_t, i.delim);
else if (ret_func != 0) ret_func(data_t, i.delim);
if (i.slot) i.slot(data_t, i.delim);
else if (ret_func) ret_func(data_t, i.delim);
tick(data_t, i.delim);
tickEvent(data_t, i.delim);
}
@@ -587,6 +582,67 @@ void PITimer::tickImp() {
}
bool PITimer::start() {
piCout << this << "start" << imp;
return imp->start();
}
bool PITimer::start(double interval_ms_d) {
init();
piCout << this << "start" << imp << interval_ms_d;
setProperty("interval", interval_ms_d);
return imp->start(interval_ms_d);
}
bool PITimer::start(int interval_ms_i) {
return start((double)interval_ms_i);
}
void PITimer::startDeferred(double delay_ms) {
init();
imp->startDeferred(delay_ms);
}
void PITimer::startDeferred(double interval_ms, double delay_ms) {
init();
imp->startDeferred(interval_ms, delay_ms);
}
void PITimer::startDeferred(PIDateTime start_datetime) {
startDeferred(imp->interval_, start_datetime);
}
void PITimer::startDeferred(double interval_ms, PIDateTime start_datetime) {
init();
imp->startDeferred(interval_ms, start_datetime);
}
bool PITimer::restart() {
init();
imp->stop(true);
return imp->start();
}
bool PITimer::stop() {
return stop(true);
}
bool PITimer::stop(bool wait) {
init();
piCout << this << "stop" << imp << wait;
return imp->stop(wait);
}
bool PITimer::waitForFinish(int timeout_msecs) {
if (timeout_msecs < 0) {
while (isRunning())

View File

@@ -103,45 +103,45 @@ public:
PITimer::TimerImplementation implementation() const {return imp_mode;}
//! \brief Returns timer loop delay in milliseconds
double interval() const {return imp->interval_;}
double interval() const;
//! \brief Set timer loop delay in milliseconds
EVENT_HANDLER1(void, setInterval, double, ms) {setProperty("interval", ms); imp->setInterval(ms);}
EVENT_HANDLER1(void, setInterval, double, ms);
//! \brief Returns if timer is started
bool isRunning() const {return imp->running_;}
bool isRunning() const;
//! \brief Returns if timer is not started
bool isStopped() const {return !imp->running_;}
bool isStopped() const;
EVENT_HANDLER0(bool, start) {return imp->start();}
EVENT_HANDLER1(bool, start, double, interval_ms_d) {setProperty("interval", interval_ms_d); return imp->start(interval_ms_d);}
bool start(int interval_ms_i) {setProperty("interval", double(interval_ms_i)); return imp->start(double(interval_ms_i));}
EVENT_HANDLER0(bool, restart) {imp->stop(true); return imp->start();}
EVENT_HANDLER0(bool, start);
EVENT_HANDLER1(bool, start, double, interval_ms_d);
bool start(int interval_ms_i);
EVENT_HANDLER0(bool, restart);
/** \brief Start timer with \b interval() loop delay after \b delay_msecs delay.
* \details Timer wait \b delay_msecs milliseconds and then normally starts with
* \b interval() loop delay. */
void startDeferred(double delay_ms) {imp->startDeferred(delay_ms);}
void startDeferred(double delay_ms);
/** \brief Start timer with \b interval_msecs loop delay after \b delay_msecs delay.
* \details Timer wait \b delay_msecs milliseconds and then normally starts with
* \b interval_msecs loop delay. */
void startDeferred(double interval_ms, double delay_ms) {imp->startDeferred(interval_ms, delay_ms);}
void startDeferred(double interval_ms, double delay_ms);
/** \brief Start timer with \b interval() loop delay after \b start_datetime date and time.
* \details Timer wait until \b start_datetime and then normally starts with
* \b interval() loop delay. */
void startDeferred(PIDateTime start_datetime) {startDeferred(imp->interval_, start_datetime);}
void startDeferred(PIDateTime start_datetime);
/** \brief Start timer with \b interval_msecs loop delay after \b start_datetime date and time.
* \details Timer wait until \b start_datetime and then normally starts with
* \b interval_msecs loop delay. */
void startDeferred(double interval_ms, PIDateTime start_datetime) {imp->startDeferred(interval_ms, start_datetime);}
void startDeferred(double interval_ms, PIDateTime start_datetime);
EVENT_HANDLER0(bool, stop) {return imp->stop(true);}
EVENT_HANDLER1(bool, stop, bool, wait) {return imp->stop(wait);}
EVENT_HANDLER0(bool, stop);
EVENT_HANDLER1(bool, stop, bool, wait);
bool waitForFinish() {return waitForFinish(-1);}
bool waitForFinish(int timeout_msecs);
@@ -222,7 +222,7 @@ protected:
};
void initFirst();
void init();
void init() const;
void destroy();
static void tickImpS(PITimer * t) {t->tickImp();}
@@ -239,11 +239,11 @@ protected:
TimerImplementation imp_mode;
PIVector<Delimiter> delims;
_PITimerBase * imp;
mutable _PITimerBase * imp;
private:
explicit PITimer(const PITimer & );
void operator =(const PITimer & );
NO_COPY_CLASS(PITimer)
};