1 /******************************************************************************
2 * Copyright (c) 2000-2014 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 ******************************************************************************/
11 modulepar float tsp_EPTF_maxRunningTime := 2147483.0;
13 modulepar integer tsp_CLL_debug_acceptableMaxSizeOfGrowingVariables := -1;
14 modulepar float tsp_CLL_debug_increasePercentage4AcceptableMaxSize := 0.1;
16 type record of default EPTF_DefaultList;
17 type record of integer EPTF_IntegerList;
19 type record of EPTF_IntegerList EPTF_IntegerArray2D;
21 type record of charstring EPTF_CharstringList;
23 type record of float EPTF_FloatList;
25 type record of boolean EPTF_BooleanList;
27 type enumerated EPTF_LEDColors {
35 type record EPTF_StatusLED {
37 charstring text optional
40 type record EPTF_ParamRangeDescriptor{
47 type record of EPTF_ParamRangeDescriptor EPTF_ParamRangeDescriptorList;
49 const boolean c_EPTF_Common_debugSwitch := true;
51 public external function f_EPTF_Common_error(in charstring pl_message);
52 public external function f_EPTF_Common_warning(in charstring pl_message);
53 public external function f_EPTF_Common_user(in charstring pl_message);
55 private external function f_EPTF_Common_initErrorMsgs();
57 public function f_EPTF_Common_init() {
58 f_EPTF_Common_initErrorMsgs();
61 public external function f_EPTF_Common_nofErrorMsgs() return integer;
62 public external function f_EPTF_Common_getErrorMsg(in integer pl_errorNum := 0) return charstring;
64 public function f_EPTF_Common_checkExpectedError(in charstring pl_expectedError, in integer pl_errorNum := 0) return boolean {
65 if (not match(f_EPTF_Common_getErrorMsg(pl_errorNum), pattern pl_expectedError)) {
66 f_EPTF_Common_warning("Warning: "&%definitionId& ": Error message with id "&int2str(pl_errorNum)&" is different from the expected pattern: "&
67 log2str(match(f_EPTF_Common_getErrorMsg(pl_errorNum), pattern pl_expectedError)));
70 f_EPTF_Common_user(%definitionId& ": Error message with id "&int2str(pl_errorNum)&" matches with the expected pattern: "& pl_expectedError);
77 public function f_EPTF_Common_resetParamRanges(inout EPTF_ParamRangeDescriptorList pl_rangeList) {
78 for (var integer i:=0;i<sizeof(pl_rangeList);i:=i+1) {
79 pl_rangeList[i].iterator := pl_rangeList[i].baseOffset;
83 public function f_EPTF_Common_incParamRanges(inout EPTF_ParamRangeDescriptorList pl_rangeList) return boolean {
85 for (i:=sizeof(pl_rangeList)-1;i>=0 and f_EPTF_Common_private_incParamRangeItem(pl_rangeList[i]);i:=i-1) {}
86 if (i<0) {return true}
90 public function f_EPTF_Common_private_incParamRangeItem(inout EPTF_ParamRangeDescriptor pl_range) return boolean {
91 pl_range.iterator := pl_range.iterator + 1;
92 if (pl_range.baseOffset + pl_range.count>pl_range.iterator) {return false}
93 pl_range.iterator := pl_range.baseOffset;
101 public function f_EPTF_Common_fillWeightedBuckets(in EPTF_FloatList pl_weightList, in integer pl_nrOfElements, out EPTF_IntegerList pl_result) return boolean
104 if (sizeof(pl_weightList)<1) {
105 f_EPTF_Common_user(log2str(%definitionId,": empty weightList, unable to split"));
109 if (sizeof(pl_weightList)>pl_nrOfElements) {
110 f_EPTF_Common_user(log2str(%definitionId,": not enough elements, unable to split"));
114 var EPTF_IntegerList vl_sortedWeightsIdx := {};
115 for (var integer i:=0;i<sizeof(pl_weightList);i:=i+1) {
116 vl_sortedWeightsIdx[i] := i;
119 var integer vl_tmpint;
120 for (var integer i:=sizeof(pl_weightList)-1;i>=0;i:=i-1) {
121 for (var integer j:=0;j<i;j:=j+1) {
122 if (pl_weightList[vl_sortedWeightsIdx[j]]>pl_weightList[vl_sortedWeightsIdx[j+1]]) {
123 vl_tmpint := vl_sortedWeightsIdx[j];
124 vl_sortedWeightsIdx[j] := vl_sortedWeightsIdx[j+1];
125 vl_sortedWeightsIdx[j+1] := vl_tmpint;
130 var integer vl_nrOfUsedElements := 0;
132 for (var integer i:=0;i<sizeof(pl_weightList)-1;i:=i+1) {
133 pl_result[vl_sortedWeightsIdx[i]] := float2int(pl_weightList[vl_sortedWeightsIdx[i]] * int2float(pl_nrOfElements));
134 if (pl_result[vl_sortedWeightsIdx[i]]<1) {pl_result[vl_sortedWeightsIdx[i]] := 1}
135 vl_nrOfUsedElements := vl_nrOfUsedElements + pl_result[vl_sortedWeightsIdx[i]];
137 pl_result[vl_sortedWeightsIdx[sizeof(pl_weightList)-1]] := pl_nrOfElements - vl_nrOfUsedElements;
143 type record EPTF_Common_IndexArray{
144 EPTF_IntegerList values,
147 const EPTF_Common_IndexArray c_EPTF_emptyCommon_IndexArray := {
152 function f_EPTF_Common_IndexArray_getOrCreateFreeSlot(inout EPTF_Common_IndexArray pl_array) return integer{
153 for ( var integer vl_i := 0; vl_i < sizeof(pl_array.values) ; vl_i := vl_i+1 ){
154 if(pl_array.values[vl_i] < 0){
158 return sizeof(pl_array.values)
161 function f_EPTF_Common_IndexArray_getElement(
162 inout EPTF_Common_IndexArray pl_array,
165 if(pl_idx >= 0 and pl_idx < sizeof(pl_array.values)){
166 return pl_array.values[pl_idx]
171 function f_EPTF_Common_IndexArray_setElement(
172 inout EPTF_Common_IndexArray pl_array,
174 in integer pl_data := -1){
176 f_EPTF_Common_error(%definitionId&": using a negative index: "&int2str(pl_idx));
179 if(0 > pl_data){pl_data := pl_idx}
180 pl_array.values[pl_idx] := pl_data;
181 if((pl_array.firstBusy > pl_idx) or (0 > pl_array.firstBusy)){
182 pl_array.firstBusy := pl_idx
184 for ( var integer vl_i := (pl_idx - 1); vl_i >= 0 and not isvalue(pl_array.values[vl_i]) ; vl_i := vl_i - 1 ){
185 pl_array.values[vl_i] := -1;
189 function f_EPTF_Common_IndexArray_setNewElement(
190 inout EPTF_Common_IndexArray pl_array,
191 in integer pl_data := -1)
193 var integer vl_idx := f_EPTF_Common_IndexArray_getOrCreateFreeSlot(pl_array)
194 if(0 > pl_data){pl_data := vl_idx}
195 pl_array.values[vl_idx] := pl_data;
196 if((pl_array.firstBusy > vl_idx) or (0 > pl_array.firstBusy)){
197 pl_array.firstBusy := vl_idx
202 function f_EPTF_Common_IndexArray_freeElement(
203 inout EPTF_Common_IndexArray pl_array,
206 var integer vl_ret := -1
207 if(pl_idx >= 0 and pl_idx < sizeof(pl_array.values)){
208 vl_ret := pl_array.values[pl_idx]
209 pl_array.values[pl_idx] := -1
210 if(pl_idx == pl_array.firstBusy){
211 pl_array.firstBusy := -1
212 for ( var integer vl_i := pl_idx+1; vl_i < sizeof(pl_array.values) and -1 == pl_array.firstBusy ; vl_i := vl_i+1 ){
213 if(0 <= pl_array.values[vl_i]){
214 pl_array.firstBusy := vl_i
222 function f_EPTF_Common_IndexArray_arrayIsEmpty(
223 inout EPTF_Common_IndexArray pl_array)
225 return -1 == pl_array.firstBusy
228 function f_EPTF_Common_IndexArray_getFirstBusyIdx(
229 inout EPTF_Common_IndexArray pl_array)
231 return pl_array.firstBusy
234 function f_EPTF_Common_IndexArray_getNextBusyIdx(
235 inout EPTF_Common_IndexArray pl_array,
238 if(pl_idx >= 0 and pl_idx < sizeof(pl_array.values)){
239 for ( var integer vl_i := pl_idx+1; vl_i < sizeof(pl_array.values) ; vl_i := vl_i+1 ){
240 if(0 <= pl_array.values[vl_i]){
248 modulepar boolean tsp_EPTF_Base_serialStopAllComponents := true;
250 type function f_EPTF_Feature_cleanup_CT() runs on self;
252 type record of f_EPTF_Feature_cleanup_CT EPTF_Base_CleanupFunctions;
254 type record of EPTF_Base_CT EPTF_Base_ComponentList;
256 type union EPTF_Base_MgmtMsg {
257 EPTF_Base_Msg_Hello hello,
258 EPTF_Base_Msg_Bye bye,
259 EPTF_Base_Msg_ByeAck byeAck,
260 EPTF_Base_Msg_StopRemote stopRemote
263 type record EPTF_Base_Msg_Hello {
266 type EPTF_Base_Msg_Hello EPTF_Base_Msg_Bye;
268 type EPTF_Base_Msg_Hello EPTF_Base_Msg_ByeAck;
270 type record EPTF_Base_Msg_StopRemote {
274 type port EPTF_Base_Mgmt_PT message {
275 inout EPTF_Base_MgmtMsg;
276 } with { extension "internal" }
278 type component EPTF_Base_CT extends EPTF_Base_CT_private {
281 friend module EPTF_CLL_Base_Functions;
282 friend type component EPTF_Base_CT_private {
283 private var charstring v_selfName;
284 private var boolean v_EPTF_Base_initialized := false;
285 private var EPTF_Base_CleanupFunctions v_EPTF_Base_cleanupFunctions := {};
286 private port EPTF_Base_Mgmt_PT EPTF_Base_MgmtIf;
287 private var default v_EPTF_Base_def;
288 private var EPTF_Base_ComponentList v_EPTF_Base_componentsToStop := {};
289 private var boolean v_EPTF_Base_serialStopAllComponents := tsp_EPTF_Base_serialStopAllComponents;
290 private var boolean v_EPTF_Base_disableBye := false;
291 private var boolean v_EPTF_Base_byeAckReceived := false;
292 private var EPTF_Base_CT v_EPTF_Base_stopRemoteSentTo := null;
293 timer T_EPTF_componentClock := tsp_EPTF_maxRunningTime;
294 private var float v_EPTF_Base_abstimeOfZeroComponentClock := 0.0;
296 private var boolean v_EPTF_Base_negativeTestMode := false;
297 private var EPTF_CharstringList v_EPTF_Base_assertMsgs := {};
298 private var charstring v_EPTF_Base_expectedAssert := "";
299 private var charstring v_EPTF_Base_expectedError := "";
304 public function f_EPTF_Base_init_CT(in charstring pl_selfName) runs on EPTF_Base_CT_private {
305 if (v_EPTF_Base_initialized) {
308 v_selfName := pl_selfName;
309 v_EPTF_Base_cleanupFunctions := {};
310 v_EPTF_Base_componentsToStop := {};
311 v_EPTF_Base_disableBye := false;
312 v_EPTF_Base_byeAckReceived := false;
313 v_EPTF_Base_stopRemoteSentTo := null;
314 v_EPTF_Base_negativeTestMode := false;
315 v_EPTF_Base_assertMsgs := {};
316 v_EPTF_Base_expectedAssert := "";
317 v_EPTF_Base_expectedError := "";
320 connect(self:EPTF_Base_MgmtIf,mtc:EPTF_Base_MgmtIf);
321 f_EPTF_Base_send({hello := {}},mtc);
322 disconnect(self:EPTF_Base_MgmtIf,mtc:EPTF_Base_MgmtIf);
324 T_EPTF_componentClock.start;
325 v_EPTF_Base_abstimeOfZeroComponentClock := f_EPTF_Base_getTimeOfDay();
326 v_EPTF_Base_def := activate(as_handle_main_EPTF_Base_MgmtIf());
327 v_EPTF_Base_initialized := true;
329 f_EPTF_Base_registerCleanup(refers(f_EPTF_Base_cleanup_CT));
330 f_EPTF_Common_user(log2str("----BASE INIT DONE FOR COMPONENT ",v_selfName,"----"));
333 public function f_EPTF_Base_registerCleanup(in f_EPTF_Feature_cleanup_CT pl_featureCleanupFn) runs on EPTF_Base_CT_private {
334 if (v_EPTF_Base_initialized == false) {
335 f_EPTF_Common_error(log2str("ERROR:","f_EPTF_Base_init_CT is not called before calling f_EPTF_Base_registerCleanup for ", pl_featureCleanupFn));
337 for (var integer i:=0; i<sizeof(v_EPTF_Base_cleanupFunctions); i:=i+1) {
338 if (pl_featureCleanupFn == v_EPTF_Base_cleanupFunctions[i]) {
342 v_EPTF_Base_cleanupFunctions[sizeof(v_EPTF_Base_cleanupFunctions)] := pl_featureCleanupFn;
345 public function f_EPTF_Base_cleanup_CT() runs on EPTF_Base_CT_private {
346 if (v_EPTF_Base_initialized == false) {
349 v_EPTF_Base_initialized := false;
351 f_EPTF_Common_user("----BASE CLEANUP START----");
353 f_EPTF_Base_stopAllComponents();
356 for (var integer i:=sizeof(v_EPTF_Base_cleanupFunctions)-1; i>-1; i:=i-1) {
357 f_EPTF_Common_user(log2str("DEBUG:","Calling cleanup function ",v_EPTF_Base_cleanupFunctions[i]));
358 v_EPTF_Base_cleanupFunctions[i].apply();
359 f_EPTF_Common_user(log2str("DEBUG:","Cleanup function done ",v_EPTF_Base_cleanupFunctions[i]));
362 if (v_EPTF_Base_expectedAssert!="") {
363 if (f_EPTF_Base_checkExpectedAssert(v_EPTF_Base_expectedAssert)) {
369 if (v_EPTF_Base_expectedError!="") {
370 if (f_EPTF_Base_checkExpectedError(v_EPTF_Base_expectedError)) {
378 f_EPTF_Base_stopAllComponents();
379 timer t_periodicStop := 2.0;
380 t_periodicStop.start;
382 [] all component.done;
383 [] t_periodicStop.timeout {
384 f_EPTF_Base_stopAllComponents();
385 t_periodicStop.start;
390 if (v_EPTF_Base_disableBye == false) {
391 connect(self:EPTF_Base_MgmtIf,mtc:EPTF_Base_MgmtIf);
392 f_EPTF_Base_send({bye := {}},mtc);
393 f_EPTF_Base_waitForByeAck();
394 disconnect(self:EPTF_Base_MgmtIf,mtc:EPTF_Base_MgmtIf);
398 if(T_EPTF_componentClock.running) { T_EPTF_componentClock.stop; }
400 v_EPTF_Base_stopRemoteSentTo := null;
401 f_EPTF_Common_user(log2str("----BASE CLEANUP DONE FOR ",v_selfName,"----"));
404 public function f_EPTF_Base_stop(in verdicttype pl_verdict := fail) runs on EPTF_Base_CT_private {
405 if (v_EPTF_Base_initialized == false) {
406 f_EPTF_Common_warning(log2str("Warning:","Cleanup is in progress, additional stop is ignored."));
409 if (pl_verdict != none and not v_EPTF_Base_negativeTestMode) {
410 setverdict(pl_verdict);
412 f_EPTF_Common_user("Trying to stop execution gracefully...");
413 f_EPTF_Base_cleanup_CT();
417 public function f_EPTF_Base_stopRemote(in EPTF_Base_CT_private pl_remoteComp, in boolean pl_noCleanup := false) runs on EPTF_Base_CT_private {
418 f_EPTF_Common_user(log2str("Requesting to stop execution of component ",pl_remoteComp," gracefully..."));
421 f_EPTF_Base_removeComponent(pl_remoteComp);
424 if (pl_remoteComp == mtc) {
425 if (v_EPTF_Base_initialized == false) {
426 f_EPTF_Common_warning(log2str("Warning:","Cleanup is in progress, additional stopRemote is ignored for pl_remoteComp: mtc."));
430 connect(self:EPTF_Base_MgmtIf,pl_remoteComp:EPTF_Base_MgmtIf);
431 f_EPTF_Base_send({stopRemote := {pl_noCleanup}},pl_remoteComp);
432 disconnect(self:EPTF_Base_MgmtIf,pl_remoteComp:EPTF_Base_MgmtIf);
434 if (pl_noCleanup == false) {
435 v_EPTF_Base_disableBye := true;
436 f_EPTF_Base_cleanup_CT();
440 connect(self:EPTF_Base_MgmtIf,pl_remoteComp:EPTF_Base_MgmtIf);
441 f_EPTF_Base_send({stopRemote := {pl_noCleanup}},pl_remoteComp);
444 public function f_EPTF_Base_stopAll(in verdicttype pl_verdict := fail, in boolean pl_noCleanup := false) runs on EPTF_Base_CT_private {
445 if (pl_verdict != none and not v_EPTF_Base_negativeTestMode) {
446 setverdict(pl_verdict);
448 f_EPTF_Common_user("Trying to stop execution of all components gracefully...");
449 f_EPTF_Base_stopRemote(mtc,pl_noCleanup);
452 public function f_EPTF_Base_selfName() runs on EPTF_Base_CT_private return charstring {
456 public function f_EPTF_Base_cleanupIsInProgress() runs on EPTF_Base_CT_private return boolean {
457 return v_EPTF_Base_initialized;
460 public function f_EPTF_Base_wait4Shutdown() runs on EPTF_Base_CT_private
462 T_EPTF_componentClock.timeout;
465 public function f_EPTF_Base_getRelTimeInSecs()
466 runs on EPTF_Base_CT_private
469 return T_EPTF_componentClock.read;
472 public function f_EPTF_Base_getRelTimeOffsetInSecs()
473 runs on EPTF_Base_CT_private
476 return v_EPTF_Base_abstimeOfZeroComponentClock;
479 public function f_EPTF_Base_getAbsTimeInSecs()
480 runs on EPTF_Base_CT_private
483 return v_EPTF_Base_abstimeOfZeroComponentClock + T_EPTF_componentClock.read;
486 public external function f_EPTF_Base_upcast(in EPTF_Base_CT pl_compRef) return integer;
488 public external function f_EPTF_Base_downcast(in integer pl_baseCompRef) return EPTF_Base_CT;
490 public function f_EPTF_Base_setNegativeTestMode(in boolean pl_negativeTest := true) runs on EPTF_Base_CT_private {
491 action(%definitionId&": THIS IS A NEGATIVE TEST, VERDICT SHOULD BE PASS!");
492 v_EPTF_Base_negativeTestMode:= pl_negativeTest;
495 public function f_EPTF_Base_getNegativeTestMode()
496 runs on EPTF_Base_CT_private
498 return v_EPTF_Base_negativeTestMode;
501 public external function f_EPTF_Base_assert(in charstring pl_assertMessage,in boolean pl_predicate);
503 private function f_EPTF_Base_addAssertMsg(in charstring pl_newMsg) runs on EPTF_Base_CT_private {
504 v_EPTF_Base_assertMsgs[sizeof(v_EPTF_Base_assertMsgs)] := pl_newMsg;
507 public function f_EPTF_Base_nofAssertMsgs() runs on EPTF_Base_CT_private return integer {
508 return sizeof(v_EPTF_Base_assertMsgs);
511 public function f_EPTF_Base_getAssertMsg(in integer pl_assertNum := 0) runs on EPTF_Base_CT_private return charstring {
512 if (sizeof(v_EPTF_Base_assertMsgs)==0) {
515 if (sizeof(v_EPTF_Base_assertMsgs)<=pl_assertNum or pl_assertNum<0) {
518 return v_EPTF_Base_assertMsgs[pl_assertNum];
521 public function f_EPTF_Base_setExpectedAssertMsg(in charstring pl_expectedAssert) runs on EPTF_Base_CT_private {
522 v_EPTF_Base_expectedAssert := pl_expectedAssert;
523 if("" != v_EPTF_Base_expectedError){
524 f_EPTF_Common_warning(%definitionId&": There is already an expected error message: "&v_EPTF_Base_expectedError&
525 " This may cause ambiguous behavior!")
527 f_EPTF_Base_setNegativeTestMode()
530 public function f_EPTF_Base_setExpectedErrorMsg(in charstring pl_expectedError) runs on EPTF_Base_CT_private {
531 v_EPTF_Base_expectedError := pl_expectedError;
532 if("" != v_EPTF_Base_expectedAssert){
533 f_EPTF_Common_warning(%definitionId&": There is already an expected assert message: "&v_EPTF_Base_expectedAssert&
534 " This may cause ambiguous behavior!")
536 f_EPTF_Base_setNegativeTestMode()
539 public function f_EPTF_Base_checkExpectedAssert(in charstring pl_expectedAssert, in integer pl_assertNum := 0)
540 runs on EPTF_Base_CT_private return boolean {
541 if (not match(f_EPTF_Base_getAssertMsg(pl_assertNum), pattern pl_expectedAssert)) {
542 f_EPTF_Common_warning("Warning: "&%definitionId& ": Assert message with id "&int2str(pl_assertNum)&" is different from the expected pattern: "&
543 log2str(match(f_EPTF_Base_getAssertMsg(pl_assertNum), pattern pl_expectedAssert)));
546 f_EPTF_Common_user(%definitionId& ": Assert message with id "&int2str(pl_assertNum)&" matches with the expected pattern: "& pl_expectedAssert);
552 public function f_EPTF_Base_checkExpectedError(in charstring pl_expectedError, in integer pl_errNum := 0)
553 runs on EPTF_Base_CT_private return boolean {
554 if (not match(f_EPTF_Common_getErrorMsg(pl_errNum), pattern pl_expectedError)) {
555 f_EPTF_Common_warning("Warning: "&%definitionId& ": Error message with id "&int2str(pl_errNum)&" is different from the expected pattern: "&
556 log2str(match(f_EPTF_Common_getErrorMsg(pl_errNum), pattern pl_expectedError)));
559 f_EPTF_Common_user(%definitionId& ": Error message with id "&int2str(pl_errNum)&" matches with the expected pattern: "& pl_expectedError);
565 public external function f_EPTF_Base_getTimeOfDay() return float;
569 function f_EPTF_Base_RegisterCleanup(in f_EPTF_Feature_cleanup_CT pl_featureCleanupFn) runs on EPTF_Base_CT_private {
570 f_EPTF_Common_warning("Warning: "&%definitionId& ": This function is deprecated and will be removed! Use f_EPTF_Base_registerCleanup instead!");
571 f_EPTF_Base_registerCleanup(pl_featureCleanupFn);
574 private function f_EPTF_Base_addComponent(in EPTF_Base_CT pl_remoteCompRef) runs on EPTF_Base_CT_private {
575 var integer vl_i := sizeof(v_EPTF_Base_componentsToStop) - 1;
576 while(vl_i >= 0 and v_EPTF_Base_componentsToStop[vl_i] == null) {
580 v_EPTF_Base_componentsToStop[vl_i] := pl_remoteCompRef;
583 private function f_EPTF_Base_removeComponent(in EPTF_Base_CT_private pl_remoteCompRef) runs on EPTF_Base_CT_private {
584 for (var integer i:=0; i<sizeof(v_EPTF_Base_componentsToStop); i := i+1) {
585 if ( v_EPTF_Base_componentsToStop[i] == pl_remoteCompRef) {
586 v_EPTF_Base_componentsToStop[i] := null;
592 private function f_EPTF_Base_stopAllComponents() runs on EPTF_Base_CT_private {
593 v_EPTF_Base_stopRemoteSentTo:=mtc;
594 for (var integer i:=sizeof(v_EPTF_Base_componentsToStop)-1; i>=0; i := i-1) {
595 if ( v_EPTF_Base_componentsToStop[i] != null) {
596 var EPTF_Base_CT vl_componentToStop := v_EPTF_Base_componentsToStop[i];
597 f_EPTF_Base_stopRemote(v_EPTF_Base_componentsToStop[i]);
598 if (v_EPTF_Base_serialStopAllComponents) {
599 vl_componentToStop.done;
600 i:=sizeof(v_EPTF_Base_componentsToStop)-1;
606 private function f_EPTF_Base_stopLastComponent() runs on EPTF_Base_CT_private{
611 for (var integer i:=sizeof(v_EPTF_Base_componentsToStop)-1; i>=0; i := i-1) {
612 if ( v_EPTF_Base_componentsToStop[i] != null) {
613 var EPTF_Base_CT vl_componentToStop := v_EPTF_Base_componentsToStop[i];
614 f_EPTF_Base_stopRemote(v_EPTF_Base_componentsToStop[i]);
615 v_EPTF_Base_stopRemoteSentTo := vl_componentToStop;
619 f_EPTF_Common_user(log2str("All components terminated. Stopping myself (MTC)..."));
620 f_EPTF_Base_cleanup_CT();
624 private function f_EPTF_Base_send(in EPTF_Base_MgmtMsg pl_EPTF_Base_MgmtMsg, in EPTF_Base_CT_private pl_remoteCompRef) runs on EPTF_Base_CT_private {
625 EPTF_Base_MgmtIf.send(pl_EPTF_Base_MgmtMsg) to pl_remoteCompRef;
628 private function f_EPTF_Base_handle_StopRemote(in EPTF_Base_Msg_StopRemote pl_stopRemote, in EPTF_Base_CT_private pl_EPTF_Base_MgmtIf_msg_sender) runs on EPTF_Base_CT_private {
629 if (v_EPTF_Base_initialized == false) {
630 f_EPTF_Common_warning(log2str("Warning:","Cleanup is in progress, stopRemote message dropped."));
632 f_EPTF_Base_removeComponent(pl_EPTF_Base_MgmtIf_msg_sender);
636 f_EPTF_Common_user(log2str("StopRemote received from ",pl_EPTF_Base_MgmtIf_msg_sender,". Trying to stop execution gracefully..."));
638 disconnect(self:EPTF_Base_MgmtIf,pl_EPTF_Base_MgmtIf_msg_sender:EPTF_Base_MgmtIf);
640 if (pl_stopRemote.noCleanup) {
641 f_EPTF_Common_warning(log2str("Warning:","Cleanup is disabled in stopRemote message. CLEANUP IS NOT PERFORMED."));
643 if (pl_EPTF_Base_MgmtIf_msg_sender == mtc) {
644 v_EPTF_Base_disableBye := true;
647 f_EPTF_Base_removeComponent(pl_EPTF_Base_MgmtIf_msg_sender);
648 if (v_EPTF_Base_serialStopAllComponents) {
649 f_EPTF_Base_stopLastComponent();
651 f_EPTF_Base_stopAllComponents();
655 f_EPTF_Base_cleanup_CT();
660 private function f_EPTF_Base_handle_hello(in EPTF_Base_CT pl_EPTF_Base_MgmtIf_msg_sender) runs on EPTF_Base_CT_private {
661 f_EPTF_Base_addComponent(pl_EPTF_Base_MgmtIf_msg_sender);
664 private function f_EPTF_Base_handle_bye(in EPTF_Base_CT pl_EPTF_Base_MgmtIf_msg_sender) runs on EPTF_Base_CT_private {
665 f_EPTF_Base_removeComponent(pl_EPTF_Base_MgmtIf_msg_sender);
666 f_EPTF_Base_send({byeAck := {}},pl_EPTF_Base_MgmtIf_msg_sender);
669 private function f_EPTF_Base_handle_byeAck(in EPTF_Base_CT pl_EPTF_Base_MgmtIf_msg_sender) runs on EPTF_Base_CT_private {
670 v_EPTF_Base_byeAckReceived := true;
673 modulepar float tsp_EPTF_Base_maxWaitTime := 120.0;
675 private function f_EPTF_Base_waitForByeAck() runs on EPTF_Base_CT_private {
678 timer t_maxWait := tsp_EPTF_Base_maxWaitTime;
681 [v_EPTF_Base_byeAckReceived] t_wait.timeout;
682 [] t_maxWait.timeout {
683 f_EPTF_Common_warning(%definitionId&": ByeAck is not received before max wait time expired. Continuing anyway...");
688 private function f_handle_main_EPTF_Base_MgmtIf(
689 in EPTF_Base_MgmtMsg vl_EPTF_Base_MgmtIf_msg,
690 in EPTF_Base_CT vl_EPTF_Base_MgmtIf_msg_sender) runs on EPTF_Base_CT_private return boolean {
691 if (ischosen(vl_EPTF_Base_MgmtIf_msg.stopRemote)) {
692 f_EPTF_Base_handle_StopRemote(vl_EPTF_Base_MgmtIf_msg.stopRemote,vl_EPTF_Base_MgmtIf_msg_sender);
695 if (ischosen(vl_EPTF_Base_MgmtIf_msg.hello)) {
696 f_EPTF_Base_handle_hello(vl_EPTF_Base_MgmtIf_msg_sender);
699 if (ischosen(vl_EPTF_Base_MgmtIf_msg.bye)) {
700 f_EPTF_Base_handle_bye(vl_EPTF_Base_MgmtIf_msg_sender);
703 if (ischosen(vl_EPTF_Base_MgmtIf_msg.byeAck)) {
704 f_EPTF_Base_handle_byeAck(vl_EPTF_Base_MgmtIf_msg_sender);
708 f_EPTF_Common_error(log2str("ERROR:","Unexpected message received from ",vl_EPTF_Base_MgmtIf_msg_sender,": ",vl_EPTF_Base_MgmtIf_msg));
712 private altstep as_EPTF_Base_stopAllComponents() runs on EPTF_Base_CT_private {
713 [self==mtc and v_EPTF_Base_stopRemoteSentTo!=null and v_EPTF_Base_stopRemoteSentTo!=mtc] v_EPTF_Base_stopRemoteSentTo.done {
714 f_EPTF_Base_stopLastComponent();
717 [self==mtc and v_EPTF_Base_stopRemoteSentTo==mtc and v_EPTF_Base_initialized] all component.done {
718 f_EPTF_Base_stopLastComponent();
723 private altstep as_handle_main_EPTF_Base_MgmtIf() runs on EPTF_Base_CT_private {
724 var EPTF_Base_MgmtMsg vl_EPTF_Base_MgmtIf_msg;
725 var EPTF_Base_CT vl_EPTF_Base_MgmtIf_msg_sender;
726 [] EPTF_Base_MgmtIf.receive(*) -> value vl_EPTF_Base_MgmtIf_msg sender vl_EPTF_Base_MgmtIf_msg_sender {
727 if (f_handle_main_EPTF_Base_MgmtIf(vl_EPTF_Base_MgmtIf_msg,vl_EPTF_Base_MgmtIf_msg_sender)) {repeat;}
729 [] as_EPTF_Base_stopAllComponents();