Line data Source code
1 : /* 2 : * 3 : * 4 : * Distributed under the OpenDDS License. 5 : * See: http://www.opendds.org/license.html 6 : */ 7 : 8 : #include "DCPS/DdsDcps_pch.h" //Only the _pch include should start with DCPS/ 9 : 10 : #include "debug.h" 11 : #include "PeriodicEvent.h" 12 : 13 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 14 : 15 : namespace OpenDDS { 16 : namespace DCPS { 17 : 18 3 : PeriodicEvent::PeriodicEvent(EventDispatcher_rch dispatcher, EventBase_rch event) 19 3 : : dispatcher_(dispatcher) 20 3 : , event_(event) 21 3 : , strict_timing_(true) 22 6 : , timer_id_(0) 23 : { 24 3 : } 25 : 26 8 : void PeriodicEvent::enable(const TimeDuration& period, bool immediate_dispatch, bool strict_timing) 27 : { 28 8 : const MonotonicTimePoint now = MonotonicTimePoint::now(); 29 8 : ACE_Guard<ACE_Thread_Mutex> guard(mutex_); 30 8 : if (timer_id_ < 1) { 31 4 : EventDispatcher_rch dispatcher = dispatcher_.lock(); 32 4 : if (dispatcher) { 33 4 : const MonotonicTimePoint expiration = now + period; 34 4 : long id = dispatcher->schedule(rchandle_from(this), expiration); 35 4 : if (id > 0) { 36 4 : period_ = period; 37 4 : expiration_ = expiration; 38 4 : timer_id_ = id; 39 4 : strict_timing_ = strict_timing; 40 4 : if (immediate_dispatch) { 41 1 : dispatcher->dispatch(rchandle_from(this)); 42 : } 43 0 : } else if (log_level >= LogLevel::Warning) { 44 0 : ACE_ERROR((LM_WARNING, "(%P|%t) PeriodicEvent::enable: failed to schedule\n")); 45 : } 46 4 : } 47 4 : } 48 8 : } 49 : 50 4 : void PeriodicEvent::disable() 51 : { 52 4 : ACE_Guard<ACE_Thread_Mutex> guard(mutex_); 53 4 : if (timer_id_ > 0) { 54 4 : EventDispatcher_rch dispatcher = dispatcher_.lock(); 55 4 : if (dispatcher) { 56 4 : if (dispatcher->cancel(timer_id_)) { 57 4 : timer_id_ = 0; 58 : } 59 : } 60 4 : } 61 4 : } 62 : 63 4 : bool PeriodicEvent::enabled() const 64 : { 65 4 : ACE_Guard<ACE_Thread_Mutex> guard(mutex_); 66 4 : return timer_id_ > 0; 67 4 : } 68 : 69 7 : void PeriodicEvent::handle_event_scheduling() 70 : { 71 7 : ACE_Guard<ACE_Thread_Mutex> guard(mutex_); 72 7 : timer_id_ = 0; 73 7 : EventDispatcher_rch dispatcher = dispatcher_.lock(); 74 7 : if (dispatcher) { 75 7 : const MonotonicTimePoint expiration = (strict_timing_ ? expiration_ : MonotonicTimePoint::now()) + period_; 76 7 : long id = dispatcher->schedule(rchandle_from(this), expiration); 77 7 : if (id > 0) { 78 7 : expiration_ = expiration; 79 7 : timer_id_ = id; 80 : } 81 7 : } 82 7 : } 83 : 84 7 : void PeriodicEvent::handle_event() 85 : { 86 7 : handle_event_scheduling(); 87 7 : ACE_Guard<ACE_Thread_Mutex> guard(event_mutex_); 88 7 : if (event_) { 89 7 : RcHandle<EventBase> event_copy(event_); 90 7 : guard.release(); 91 7 : event_copy->handle_event(); 92 7 : } 93 7 : } 94 : 95 5 : void PeriodicEvent::handle_cancel() 96 : { 97 5 : ACE_Guard<ACE_Thread_Mutex> guard(event_mutex_); 98 5 : if (event_) { 99 5 : RcHandle<EventBase> event_copy(event_); 100 5 : guard.release(); 101 5 : event_copy->handle_cancel(); 102 5 : } 103 5 : } 104 : 105 : } // DCPS 106 : } // OpenDDS 107 : 108 : OPENDDS_END_VERSIONED_NAMESPACE_DECL