@@ -19,91 +19,34 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
1919
2020/* virtual */ const string Launcher::Initialize (PluginHost::IShell* service)
2121{
22- Time time ;
22+ Core:: Time scheduleTime ;
2323 Time interval;
24- mode timeMode = RELATIVE;
2524 string message;
2625 Config config;
2726
2827 ASSERT (_service == nullptr );
2928 ASSERT (_memory == nullptr );
29+ ASSERT (_activity.IsValid () == false );
3030
3131 // Setup skip URL for right offset.
3232 _service = service;
3333
3434 config.FromString (_service->ConfigLine ());
3535
36- if ((config.Command .IsSet () == true ) && (config.Command .Value ().empty () == false )) {
37- _closeTime = (config.CloseTime .Value ());
38-
39- if (config.ScheduleTime .IsSet () == true ) {
40-
41- timeMode = config.ScheduleTime .Mode .Value ();
42-
43- time = Time (config.ScheduleTime .Time .Value ());
44- if (time.IsValid () != true ) {
45- SYSLOG (Trace::Fatal, (_T (" Time format is wrong" )));
46- }
47-
48- interval = Time (config.ScheduleTime .Interval .Value ());
49- if (interval.IsValid () != true ) {
50- SYSLOG (Trace::Fatal, (_T (" Interval format is wrong" )));
51- }
52- }
53-
36+ if ((config.Command .IsSet () == false ) || (config.Command .Value ().empty () == true )) {
37+ message = _T (" Command is not set" );
38+ }
39+ else if (ScheduleParameters (config, message, scheduleTime, interval) == true ) {
5440 _memory = Core::Service<MemoryObserverImpl>::Create<Exchange::IMemory>(0 );
5541 ASSERT (_memory != nullptr );
5642
5743 _activity = Core::ProxyType<Job>::Create (&config, interval, _memory);
58- if (_activity.IsValid () == true ) {
59- if (_activity->IsOperational () == false ) {
60- // Well if we where able to parse the parameters (if needed) we are ready to start it..
61- _observer.Register (&_notification);
62- Core::Time scheduledTime;
63- if (time.IsValid () == true ) {
64- if (timeMode == RELATIVE) { // Schedule Job at relative timing
65- scheduledTime = Core::Time::Now ();
66-
67- uint64_t timeValueToTrigger = (((time.HasHours () ? time.Hours (): 0 ) * MinutesPerHour +
68- (time.HasMinutes () ? time.Minutes (): 0 )) * SecondsPerMinute + time.Seconds ()) * MilliSecondsPerSecond;
69- scheduledTime.Add (timeValueToTrigger);
44+ ASSERT (_activity.IsValid () == true );
7045
71- }
72- else {
73- // Schedule Job at absolute timing
74- if (timeMode == ABSOLUTE_WITH_INTERVAL) {
75- scheduledTime = FindAbsoluteTimeForSchedule (time, interval);
76- }
77- else {
78- scheduledTime = FindAbsoluteTimeForSchedule (time, Time ());
79- }
80- }
81- PluginHost::WorkerPool::Instance ().Schedule (scheduledTime, _activity);
82- }
83- else {
84- PluginHost::WorkerPool::Instance ().Submit (_activity);
85- }
46+ // Well if we where able to parse the parameters (if needed) we are ready to start it..
47+ _observer.Register (&_notification);
8648
87- }
88- else {
89- _activity.Release ();
90- message = _T (" Could not parse the configuration for the job." );
91- }
92- }
93- else {
94- message = _T (" Could not create the job." );
95- }
96- }
97- else {
98- message = _T (" Command is not set" );
99- SYSLOG (Trace::Fatal, (message.c_str ()));
100- TRACE_L1 (message.c_str ());
101- }
102- if (_activity.IsValid () == false ) {
103- if (_memory != nullptr ) {
104- _memory->Release ();
105- _memory = nullptr ;
106- }
49+ _activity->Schedule (scheduleTime);
10750 }
10851
10952 return (message);
@@ -113,26 +56,16 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
11356{
11457 ASSERT (_service == service);
11558 ASSERT (_memory != nullptr );
59+ ASSERT (_acitivity.IsValid () == true );
11660
117- PluginHost::WorkerPool::Instance ().Revoke (_activity);
118-
61+ _memory->Observe (0 );
11962 _observer.Unregister (&_notification);
12063
121- if (_memory != nullptr ) {
122- _memory->Release ();
123- _memory = nullptr ;
124- }
125- if (_activity->Process ().IsActive () == true ) {
126- // First try a gentle touch....
127- _activity->Process ().Kill (false );
128-
129- // Wait for a maximum of 3 Seconds before we shoot the process!!
130- if (_activity->Process ().WaitProcessCompleted (_closeTime * 1000 ) != Core::ERROR_NONE) {
131- _activity->Process ().Kill (true );
132- _activity->Process ().WaitProcessCompleted (_closeTime * 1000 );
133- }
134- }
64+ _activity->Shutdown ();
65+ _activity.Release ();
13566
67+ _memory->Release ();
68+ _memory = nullptr ;
13669 _service = nullptr ;
13770}
13871
@@ -144,71 +77,93 @@ SERVICE_REGISTRATION(Launcher, 1, 0);
14477
14578void Launcher::Update (const ProcessObserver::Info& info)
14679{
80+ // There is always an Activity as the unregister takes place in a locked sequence. So no new notifications
81+ // Will enter after the unregister of this handler.
82+ ASSERT (_activity.IsValid () == true );
83+ ASSERT (_service != nullptr );
84+
14785 // This can potentially be called on a socket thread, so the deactivation (wich in turn kills this object) must be done
14886 // on a seperate thread. Also make sure this call-stack can be unwound before we are totally destructed.
149- if ((_activity.IsValid () == true ) && (_activity->Pid () == info.Id ())) {
150-
151- ASSERT (_service != nullptr );
87+ if ( (_activity->Pid () == info.Id ()) && (info.Event () == ProcessObserver::Info::EVENT_EXIT) ) {
15288
153- if (info.Event () == ProcessObserver::Info::EVENT_EXIT) {
89+ _memory->Observe (0 );
90+ uint32_t result = _activity->ExitCode ();
15491
155- _memory->Observe (0 );
156- if ((info.ExitCode () & 0xFFFF ) == 0 ) {
157- // Only do this if we do not need a retrigger on an intervall.
158- if (_activity->IsOperational () == false ) {
159- PluginHost::WorkerPool::Instance ().Submit (PluginHost::IShell::Job::Create (_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::AUTOMATIC));
160- }
161- else {
162- TRACE (Trace::Information, (_T (" The process has run, and completed succefully." )));
163- }
164- }
165- else {
166- PluginHost::WorkerPool::Instance ().Submit (PluginHost::IShell::Job::Create (_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE));
167- }
92+ if (result != Core::ERROR_NONE) {
93+ SYSLOG (Trace::Fatal, (_T (" FORCED Shutdown: %s by error: %d." ), _service->Callsign ().c_str (), result));
94+ PluginHost::WorkerPool::Instance ().Submit (PluginHost::IShell::Job::Create (_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE));
95+ }
96+ else if (_activity->Continuous () == false ) {
97+ TRACE (Trace::Information, (_T (" Launcher [%s] has run succesfully, deactivation requested." ), _service->Callsign ().c_str ()));
98+ PluginHost::WorkerPool::Instance ().Submit (PluginHost::IShell::Job::Create (_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::AUTOMATIC));
99+ }
100+ else {
101+ TRACE (Trace::Information, (_T (" Launcher [%s] has run succesfully, scheduled for the next run." ), _service->Callsign ().c_str ()));
168102 }
169103 }
170104}
171105
172- Core::Time Launcher::FindAbsoluteTimeForSchedule (const Time& absoluteTime, const Time& interval) {
173- Core::Time startTime = Core::Time::Now ();
174- // Go to a first viable start time (compared to the current time, in seconds)
175- Core::Time slotTime = Core::Time (startTime.Year (), startTime.Month (), startTime.Day (),
176- (absoluteTime.HasHours () ? absoluteTime.Hours () : startTime.Hours ()),
177- (absoluteTime.HasMinutes () ? absoluteTime.Minutes () : startTime.Minutes ()),
178- absoluteTime.Seconds (), 0 , false );
106+ bool Launcher::ScheduleParameters (const Config& config, string& message, Core::Time& scheduleTime, Time& interval) {
179107
180- if (interval.IsValid () == false ) {
181- if (slotTime < startTime) {
182- uint32_t jump ((absoluteTime.HasHours () ? HoursPerDay * MinutesPerHour * SecondsPerMinute :
183- (absoluteTime.HasMinutes () ? MinutesPerHour * SecondsPerMinute : SecondsPerMinute)) * MilliSecondsPerSecond);
108+ // initialize with defaults..
109+ scheduleTime = Core::Time::Now ();
110+ interval = Time ();
184111
185- slotTime.Add (jump);
186- }
187- }
188- else {
189- uint32_t intervalJump = ( (interval.HasHours () ? interval.Hours () * MinutesPerHour * SecondsPerMinute : 0 ) +
190- (interval.HasMinutes () ? interval.Minutes () * SecondsPerMinute : 0 ) +
191- interval.Seconds () ) * MilliSecondsPerSecond;
112+ // Only if a schedule section is set, we need to do something..
113+ if (config.ScheduleTime .IsSet () == true ) {
192114
193- ASSERT (intervalJump != 0 );
194- if (slotTime >= startTime) {
195- Core::Time workTime (slotTime);
115+ mode timeMode = config.ScheduleTime .Mode .Value ();
116+ Time time (config.ScheduleTime .Time .Value ());
196117
197- while (workTime.Sub (intervalJump) > startTime) {
198- slotTime.Sub (intervalJump);
199- }
118+ interval = Time (config.ScheduleTime .Interval .Value ());
119+
120+ if (time.IsValid () != true ) {
121+ message = _T (" Incorrect time format for Scheduled time." );
122+ }
123+ else if ( (config.ScheduleTime .Interval .IsSet () == true ) && (interval.IsValid () != true ) ) {
124+ message = _T (" Incorrect time format for Interval time." );
125+ }
126+ else if ( (timeMode == ABSOLUTE_WITH_INTERVAL) && ((interval.IsValid () == false ) || (interval.TimeInSeconds () == 0 )) ) {
127+ message = _T (" Requested mode is ABSOLUTE WITH INTERVAL but no interval (or 0 second interval) is given." );
200128 }
201129 else {
202- // Now increment with the intervall till we reach a valid point
203- while (slotTime < startTime) {
204- slotTime.Add (intervalJump);
130+ // All signals green, we have valid input, calculate the ScheduleTime/Interval time
131+ if (timeMode == RELATIVE) { // Schedule Job at relative timing
132+ scheduleTime.Add (time.TimeInSeconds () * Time::MilliSecondsPerSecond);
133+ }
134+ else {
135+ Core::Time now (scheduleTime);
136+ // Go to a first viable start time (compared to the current time, in seconds)
137+ scheduleTime = Core::Time (now.Year (), now.Month (), now.Day (),
138+ (time.HasHours () ? time.Hours () : now.Hours ()),
139+ (time.HasMinutes () ? time.Minutes () : now.Minutes ()),
140+ time.Seconds (), 0 , false );
141+
142+ if (timeMode == ABSOLUTE_WITH_INTERVAL) {
143+ uint32_t intervalJump = interval.TimeInSeconds () * Time::MilliSecondsPerSecond;
144+
145+ if (scheduleTime >= now) {
146+ Core::Time workTime (scheduleTime);
147+
148+ while (workTime.Sub (intervalJump) > now) { scheduleTime.Sub (intervalJump); }
149+ }
150+ else {
151+ // Now increment with the interval till we reach a valid point
152+ while (scheduleTime < now) { scheduleTime.Add (intervalJump); }
153+ }
154+ }
155+ else if (scheduleTime < now) {
156+ uint32_t jump = (time.HasHours () ? Time::HoursPerDay * Time::MinutesPerHour * Time::SecondsPerMinute :
157+ (time.HasMinutes () ? Time::MinutesPerHour * Time::SecondsPerMinute : Time::SecondsPerMinute));
158+
159+ scheduleTime.Add (jump * Time::MilliSecondsPerSecond);
160+ }
205161 }
206162 }
207163 }
208-
209- return slotTime;
164+ return (message.empty ());
210165}
211-
166+
212167} // namespace Plugin
213168
214169} // namespace WPEFramework
0 commit comments