diff --git a/src/libCom/timer/epicsTimer.cpp b/src/libCom/timer/epicsTimer.cpp index 19e6e0ddc..a9625654f 100644 --- a/src/libCom/timer/epicsTimer.cpp +++ b/src/libCom/timer/epicsTimer.cpp @@ -48,6 +48,8 @@ private: static epicsMutex freeListMutex; }; +epicsTimer::~epicsTimer () {} + void epicsTimerNotify::show ( unsigned /* level */ ) const {} epicsTimerForC::epicsTimerForC ( timerQueue &queue, epicsTimerCallback pCBIn, void *pPrivateIn ) : @@ -55,9 +57,13 @@ epicsTimerForC::epicsTimerForC ( timerQueue &queue, epicsTimerCallback pCBIn, vo { } +epicsTimerForC::~epicsTimerForC () +{ +} + inline void epicsTimerForC::destroy () { - this->destroyTimerForC ( *this ); + this->getPrivTimerQueue().destroyTimerForC ( *this ); } epicsTimerNotify::expireStatus epicsTimerForC::expire ( const epicsTime & ) @@ -146,7 +152,7 @@ extern "C" epicsTimerId epicsShareAPI epicsTimerQueuePassiveCreateTimer ( epicsTimerQueuePassiveId pQueue, epicsTimerCallback pCallback, void *pArg ) { try { - return new epicsTimerForC ( pQueue->getTimerQueue (), pCallback, pArg ); + return & pQueue->createTimerForC ( pCallback, pArg ); } catch ( ... ) { return 0; @@ -180,7 +186,7 @@ extern "C" epicsTimerId epicsShareAPI epicsTimerQueueCreateTimer ( epicsTimerQueueId pQueue, epicsTimerCallback pCallback, void *pArg ) { try { - return new epicsTimerForC ( pQueue->getTimerQueue (), pCallback, pArg ); + return & pQueue->createTimerForC ( pCallback, pArg ); } catch ( ... ) { return 0; diff --git a/src/libCom/timer/epicsTimer.h b/src/libCom/timer/epicsTimer.h index 311072d1f..a6dfe7351 100644 --- a/src/libCom/timer/epicsTimer.h +++ b/src/libCom/timer/epicsTimer.h @@ -57,6 +57,7 @@ public: virtual expireInfo getExpireInfo () const = 0; double getExpireDelay (); virtual void show ( unsigned int level ) const = 0; + virtual class epicsTimerQueue & getQueue () const = 0; protected: virtual ~epicsTimer (); }; diff --git a/src/libCom/timer/timer.cpp b/src/libCom/timer/timer.cpp index ecc6f300d..b541b2df9 100644 --- a/src/libCom/timer/timer.cpp +++ b/src/libCom/timer/timer.cpp @@ -37,11 +37,9 @@ timer::timer ( timerQueue &queueIn ) : { } -void timer::destroyTimerForC ( epicsTimerForC &cTmr ) +timer::~timer () { - epicsAutoMutex autoLock ( this->queue.mutex ); - this->privateCancel (); - this->queue.cTimerfreeList.release ( &cTmr, sizeof(cTmr) ); + this->cancel (); } void timer::start ( epicsTimerNotify & notify, double delaySeconds ) @@ -118,11 +116,13 @@ void timer::privateCancel () { while ( true ) { if ( this->curState == statePending ) { + if ( this->queue.timerList.first() == this ) { + this->queue.notify.reschedule (); + } this->queue.timerList.remove ( *this ); this->curState = stateLimbo; this->pNotify = 0; } - // dont wait if this was called indirectly by expire () if ( this->queue.pExpireTmr == this && this->queue.processThread != epicsThreadGetIdSelf() ) { this->queue.cancelPending = true; @@ -138,6 +138,7 @@ void timer::privateCancel () } } else { + // dont wait if this was called indirectly by expire () return; } } @@ -175,3 +176,14 @@ void timer::show ( unsigned int level ) const this->pNotify->show ( level - 1u ); } } + +epicsTimerQueue & timer::getQueue () const +{ + return this->queue.getEpicsTimerQueue (); +} + +timerQueue & timer::getPrivTimerQueue() +{ + return this->queue; +} + diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h index b3ef5c8bf..bdf636af7 100644 --- a/src/libCom/timer/timerPrivate.h +++ b/src/libCom/timer/timerPrivate.h @@ -48,7 +48,8 @@ public: void cancel (); expireInfo getExpireInfo () const; void show ( unsigned int level ) const; - void destroyTimerForC ( epicsTimerForC & ); + epicsTimerQueue & getQueue () const; + class timerQueue & getPrivTimerQueue (); protected: timer ( class timerQueue & ); ~timer (); @@ -65,20 +66,21 @@ private: struct epicsTimerForC : public epicsTimerNotify, public timer { public: - epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ); void destroy (); protected: - ~epicsTimerForC (); // intentionally not implemented ( see destroy ) + epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ); + ~epicsTimerForC (); private: epicsTimerCallback pCallBack; void * pPrivate; expireStatus expire ( const epicsTime & currentTime ); + friend class timerQueue; }; class timerQueue { public: timerQueue ( epicsTimerQueueNotify ¬ify ); - ~timerQueue (); + virtual ~timerQueue (); double process ( const epicsTime & currentTime ); void show ( unsigned int level ) const; timer & createTimer (); @@ -95,6 +97,7 @@ private: timer *pExpireTmr; epicsThreadId processThread; bool cancelPending; + virtual epicsTimerQueue & getEpicsTimerQueue () = 0; friend class timer; }; @@ -110,7 +113,7 @@ private: class timerQueueActive : public epicsTimerQueueActive, public epicsThreadRunable, public epicsTimerQueueNotify, - public timerQueueActiveMgrPrivate { + public timerQueueActiveMgrPrivate, private timerQueue { public: timerQueueActive ( bool okToShare, unsigned priority ); ~timerQueueActive () = 0; @@ -119,9 +122,9 @@ public: void show ( unsigned int level ) const; bool sharingOK () const; int threadPriority () const; - timerQueue & getTimerQueue (); + epicsTimerForC & createTimerForC ( epicsTimerCallback, void *pPrivateIn ); + void destroyTimerForC ( epicsTimerForC & ); private: - timerQueue queue; epicsEvent rescheduleEvent; epicsEvent exitEvent; epicsThread thread; @@ -130,6 +133,7 @@ private: bool terminateFlag; void run (); void reschedule (); + epicsTimerQueue & getEpicsTimerQueue (); }; struct epicsTimerQueueActiveForC : public timerQueueActive, @@ -159,19 +163,19 @@ private: extern timerQueueActiveMgr queueMgr; -class timerQueuePassive : public epicsTimerQueuePassive { +class timerQueuePassive : public epicsTimerQueuePassive, + private timerQueue { public: timerQueuePassive ( epicsTimerQueueNotify & ); epicsTimer & createTimer (); void destroyTimer ( epicsTimer & ); - double process ( const epicsTime & currentTime ); void show ( unsigned int level ) const; - void release (); - timerQueue & getTimerQueue (); + double process ( const epicsTime & currentTime ); + epicsTimerForC & createTimerForC ( epicsTimerCallback, void *pPrivateIn ); + void destroyTimerForC ( epicsTimerForC & ); protected: ~timerQueuePassive (); -private: - timerQueue queue; + epicsTimerQueue & getEpicsTimerQueue (); }; inline epicsTimerForC & timerQueue::createTimerForC @@ -185,6 +189,12 @@ inline epicsTimerForC & timerQueue::createTimerForC return * new ( pBuf ) epicsTimerForC ( *this, pCB, pPriv ); } +inline void timerQueue::destroyTimerForC ( epicsTimerForC & tmr ) +{ + tmr.~epicsTimerForC (); + this->cTimerfreeList.release ( &tmr, sizeof ( tmr ) ); +} + inline bool timerQueueActive::sharingOK () const { return this->okToShare; @@ -195,16 +205,6 @@ inline int timerQueueActive::threadPriority () const return thread.getPriority (); } -inline timerQueue & timerQueueActive::getTimerQueue () -{ - return this->queue; -} - -inline timerQueue & timerQueuePassive::getTimerQueue () -{ - return this->queue; -} - inline void * epicsTimerQueueActiveForC::operator new ( size_t size ) { epicsAutoMutex locker ( epicsTimerQueueActiveForC::freeListMutex ); diff --git a/src/libCom/timer/timerQueue.cpp b/src/libCom/timer/timerQueue.cpp index db9790040..aa10c2a8d 100644 --- a/src/libCom/timer/timerQueue.cpp +++ b/src/libCom/timer/timerQueue.cpp @@ -166,7 +166,7 @@ timer & timerQueue::createTimer () void timerQueue::destroyTimer ( timer & tmr ) { epicsAutoMutex autoLock ( this->mutex ); - tmr.privateCancel (); + tmr.~timer (); this->timerFreeList.release ( &tmr, sizeof( tmr ) ); } diff --git a/src/libCom/timer/timerQueueActive.cpp b/src/libCom/timer/timerQueueActive.cpp index 40389c16e..75c543f89 100644 --- a/src/libCom/timer/timerQueueActive.cpp +++ b/src/libCom/timer/timerQueueActive.cpp @@ -41,7 +41,8 @@ epicsTimerQueueActive &epicsTimerQueueActive::allocate ( bool okToShare, int thr } timerQueueActive::timerQueueActive ( bool okToShareIn, unsigned priority ) : - queue ( *this ), thread ( *this, "epicsTimerQueueActive", + timerQueue ( static_cast ( *this ) ), + thread ( *this, "epicsTimerQueueActive", epicsThreadGetStackSize ( epicsThreadStackMedium ), priority ), okToShare ( okToShareIn ), exitFlag ( false ), terminateFlag ( false ) { @@ -63,7 +64,7 @@ void timerQueueActive::run () { this->exitFlag = false; while ( ! this->terminateFlag ) { - double delay = this->queue.process ( epicsTime::getCurrent() ); + double delay = this->timerQueue::process ( epicsTime::getCurrent() ); debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) ); this->rescheduleEvent.wait ( delay ); } @@ -73,13 +74,23 @@ void timerQueueActive::run () epicsTimer & timerQueueActive::createTimer () { - return this->queue.createTimer (); + return this->timerQueue::createTimer (); } void timerQueueActive::destroyTimer ( epicsTimer & et ) { timer & tmr = dynamic_cast < timer & > ( et ); - this->queue.destroyTimer ( tmr ); + this->timerQueue::destroyTimer ( tmr ); +} + +epicsTimerForC & timerQueueActive::createTimerForC ( epicsTimerCallback pCB, void *pPrivateIn ) +{ + return this->timerQueue::createTimerForC ( pCB, pPrivateIn ); +} + +void timerQueueActive::destroyTimerForC ( epicsTimerForC &tmr ) +{ + this->timerQueue::destroyTimerForC ( tmr ); } void timerQueueActive::reschedule () @@ -92,7 +103,7 @@ void timerQueueActive::show ( unsigned int level ) const printf ( "EPICS threaded timer queue at %p\n", static_cast ( this ) ); if ( level >=1u ) { - this->queue.show ( level - 1u ); + this->timerQueue::show ( level - 1u ); printf ( "reschedule event\n" ); this->rescheduleEvent.show ( level - 1u ); printf ( "exit event\n" ); @@ -102,3 +113,9 @@ void timerQueueActive::show ( unsigned int level ) const this->terminateFlag ? 'T' : 'F' ); } } + +epicsTimerQueue & timerQueueActive::getEpicsTimerQueue () +{ + return static_cast < epicsTimerQueue &> ( * this ); +} + diff --git a/src/libCom/timer/timerQueuePassive.cpp b/src/libCom/timer/timerQueuePassive.cpp index 8aae866b6..57b880e14 100644 --- a/src/libCom/timer/timerQueuePassive.cpp +++ b/src/libCom/timer/timerQueuePassive.cpp @@ -51,24 +51,34 @@ epicsTimerQueuePassive &epicsTimerQueuePassive::create ( epicsTimerQueueNotify & } timerQueuePassive::timerQueuePassive ( epicsTimerQueueNotify ¬ifyIn ) : - queue ( notifyIn ) {} + timerQueue ( notifyIn ) {} timerQueuePassive::~timerQueuePassive () {} epicsTimer & timerQueuePassive::createTimer () { - return this->queue.createTimer (); + return this->timerQueue::createTimer (); } void timerQueuePassive::destroyTimer ( epicsTimer & et ) { timer & tmr = dynamic_cast < timer & > ( et ); - this->queue.destroyTimer ( tmr ); + this->timerQueue::destroyTimer ( tmr ); +} + +epicsTimerForC & timerQueuePassive::createTimerForC ( epicsTimerCallback pCB, void *pPrivateIn ) +{ + return this->timerQueue::createTimerForC ( pCB, pPrivateIn ); +} + +void timerQueuePassive::destroyTimerForC ( epicsTimerForC &tmr ) +{ + this->timerQueue::destroyTimerForC ( tmr ); } double timerQueuePassive::process ( const epicsTime & currentTime ) { - return this->queue.process ( currentTime ); + return this->timerQueue::process ( currentTime ); } void timerQueuePassive::show ( unsigned int level ) const @@ -76,6 +86,12 @@ void timerQueuePassive::show ( unsigned int level ) const printf ( "EPICS non-threaded timer queue at %p\n", static_cast ( this ) ); if ( level >=1u ) { - this->queue.show ( level - 1u ); + this->timerQueue::show ( level - 1u ); } } + +epicsTimerQueue & timerQueuePassive::getEpicsTimerQueue () +{ + return static_cast < epicsTimerQueue &> ( * this ); +} +