git-svn-id: svn://db.shs.com.ru/pip@756 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
57
main.cpp
57
main.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -136,6 +136,7 @@ PICout::~PICout() {
|
||||
if (fc_) applyFormat(PICoutManipulators::Default);
|
||||
if (cc_) return;
|
||||
newLine();
|
||||
if ((co_ & NoLock) != NoLock)
|
||||
PICout::__mutex__().unlock();
|
||||
if (buffer_)
|
||||
((NotifierObject*)Notifier::object())->finished(id_, buffer_);
|
||||
@@ -427,6 +428,7 @@ void PICout::init() {
|
||||
#endif
|
||||
buffer_ = 0;
|
||||
id_ = 0;
|
||||
if ((co_ & NoLock) != NoLock)
|
||||
PICout::__mutex__().lock();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,9 @@ namespace PICoutManipulators {
|
||||
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
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user