diff --git a/main.cpp b/main.cpp index a65c7eb6..b8e81ddd 100644 --- a/main.cpp +++ b/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(); + for (;;) { + eth->send(PIByteArray::fromHex("00112233445566778899")); + piSleep(1.5); + }*/ return 0; } diff --git a/src_main/console/piconsole.cpp b/src_main/console/piconsole.cpp index f6d0a8f1..2e00290d 100644 --- a/src_main/console/piconsole.cpp +++ b/src_main/console/piconsole.cpp @@ -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; diff --git a/src_main/core/pibase.h b/src_main/core/pibase.h index a1bde517..f4edd397 100644 --- a/src_main/core/pibase.h +++ b/src_main/core/pibase.h @@ -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. diff --git a/src_main/core/picout.cpp b/src_main/core/picout.cpp index 8bca1ad4..8e48ca4f 100644 --- a/src_main/core/picout.cpp +++ b/src_main/core/picout.cpp @@ -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(); } diff --git a/src_main/core/picout.h b/src_main/core/picout.h index b5372e10..631f5da7 100644 --- a/src_main/core/picout.h +++ b/src_main/core/picout.h @@ -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 controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine); + explicit PICout(PIFlags controls = PICoutManipulators::DefaultControls); //! Construct with external buffer and id "id". See \a Notifier for details PICout(PIString * buffer, int id = 0, PIFlags controls = PICoutManipulators::AddSpaces | PICoutManipulators::AddNewLine); diff --git a/src_main/io_devices/piiodevice.cpp b/src_main/io_devices/piiodevice.cpp index 5441e4e9..a6ebfc72 100755 --- a/src_main/io_devices/piiodevice.cpp +++ b/src_main/io_devices/piiodevice.cpp @@ -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); } diff --git a/src_main/io_devices/piiodevice.h b/src_main/io_devices/piiodevice.h index c627c859..14435084 100755 --- a/src_main/io_devices/piiodevice.h +++ b/src_main/io_devices/piiodevice.h @@ -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; diff --git a/src_main/io_devices/pipeer.cpp b/src_main/io_devices/pipeer.cpp index 6a16f3ec..6f4c181a 100755 --- a/src_main/io_devices/pipeer.cpp +++ b/src_main/io_devices/pipeer.cpp @@ -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); diff --git a/src_main/io_utils/piconnection.cpp b/src_main/io_utils/piconnection.cpp index b42f45ad..575d90ef 100644 --- a/src_main/io_utils/piconnection.cpp +++ b/src_main/io_utils/piconnection.cpp @@ -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); diff --git a/src_main/io_utils/piconnection.h b/src_main/io_utils/piconnection.h index a00a818a..d739e602 100644 --- a/src_main/io_utils/piconnection.h +++ b/src_main/io_utils/piconnection.h @@ -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 devices; diff --git a/src_main/io_utils/pidiagnostics.h b/src_main/io_utils/pidiagnostics.h index b44dbf73..805d1409 100644 --- a/src_main/io_utils/pidiagnostics.h +++ b/src_main/io_utils/pidiagnostics.h @@ -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; diff --git a/src_main/thread/pimutex.h b/src_main/thread/pimutex.h index fa64305d..e2f12006 100755 --- a/src_main/thread/pimutex.h +++ b/src_main/thread/pimutex.h @@ -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(); diff --git a/src_main/thread/pithread.cpp b/src_main/thread/pithread.cpp index 5a172959..1fa0f92d 100755 --- a/src_main/thread/pithread.cpp +++ b/src_main/thread/pithread.cpp @@ -34,8 +34,8 @@ #if defined(MAC_OS) || defined(BLACKBERRY) || defined(FREERTOS) # include #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); diff --git a/src_main/thread/pithread.h b/src_main/thread/pithread.h index d551dde1..ffc4aebf 100755 --- a/src_main/thread/pithread.h +++ b/src_main/thread/pithread.h @@ -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) + }; diff --git a/src_main/thread/pitimer.cpp b/src_main/thread/pitimer.cpp index 528da0c7..fe856284 100755 --- a/src_main/thread/pitimer.cpp +++ b/src_main/thread/pitimer.cpp @@ -18,7 +18,7 @@ */ #include "pitimer.h" -#include +#include "piincludes_p.h" #ifdef PIP_TIMER_RT # include #endif @@ -73,6 +73,7 @@ bool _PITimerBase::start(double interval_ms) { if (isRunning()) stop(true); deferred_ = false; setInterval(interval_ms); + piCout << "_PITimerBase::startTimer"< 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(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()) diff --git a/src_main/thread/pitimer.h b/src_main/thread/pitimer.h index 424b8e08..dc26d36b 100755 --- a/src_main/thread/pitimer.h +++ b/src_main/thread/pitimer.h @@ -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 delims; - _PITimerBase * imp; + mutable _PITimerBase * imp; private: - explicit PITimer(const PITimer & ); - void operator =(const PITimer & ); + NO_COPY_CLASS(PITimer) + };