summaryrefslogtreecommitdiffstats
path: root/task_manager/server/src/tskm_shutdown.cpp
blob: 1699f90f9f8038f096c36b2fd39eab4b9b7faab0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tskm_shutdown.h"
#include "tskm_util.h"
#include "tskm_debug.h"
#include "tskm_state.h"

#include "tskm_port_pf.h"
#include "tskm_port_subsys.h"
#include "tskm_gstep.h"


/*********************************************************
 *        Get context of gradual startup
 *********************************************************/
TSKM_STATIC TSKM_GSTEP_CTX_t*
gstepGetDownCtx(TSKM_MAIN_CTX_t* p_main) {
  return &p_main->down;
}

/*********************************************************
 *        System shutdown completed
 *********************************************************/
TSKM_STATIC void downFinish(TSKM_MAIN_CTX_t* p_main) {
  int ret;

  // Send FrameworkunifiedOnStop response
  ret = tskm_pf_sendStopCompResp();
  if (ret != 0) {  // LCOV_EXCL_BR_LINE 8: As ret never becomes non-zero
    // LCOV_EXCL_START 8: As ret never becomes non-zero
    AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
    TSKM_ASSERT(0);
    // LCOV_EXCL_STOP
  }

  // Terminate subsystems
  tskm_sub_term();
}
/*********************************************************
 *        Challenge for a transition to the next state
 *********************************************************/
TSKM_STATIC void tryTransNextState(TSKM_MAIN_CTX_t* p_main) {
  TSKM_GSTEP_CTX_t* p_down;
  TSKM_GSTEP_t* p_current;

  p_down = gstepGetDownCtx(p_main);
  p_current = gstepGetCurrent(p_down);

  if (gstepIsLast(p_down)) {
    TSKM_SVC_WAIT_STATE_t waitState;

    // Checking the ShutdownWaitSVC termination status
    waitState = tskm_svcsGetSvcTermWaitState(&p_main->svcs);
    switch (waitState) {
      case TSKM_SVC_WAIT_BOTH:
        break;
      case TSKM_SVC_WAIT_TRANSIENT:
        if ((p_down->compState & INI_TERMCOMP_RESIDENT) != INI_TERMCOMP_RESIDENT) {
          // Nonresident service termination processing
          if (TSKM_E_OK != tskm_svcsAvtiveSvcTerm(&p_main->svcs)) {  // LCOV_EXCL_BR_LINE 5: tskm_svcsAvtiveSvcTerm is always return TSKM_E_OK
            // LCOV_EXCL_START 5: tskm_svcsAvtiveSvcTerm is always return TSKM_E_OK
            AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
            TSKM_ASSERT(0);
            // LCOV_EXCL_STOP
          }
          // Nonresident SVC terminated and started
          p_down->compState |= INI_TERMCOMP_RESIDENT;
          TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx)",
                      tskm_convTermCompId2Str(INI_TERMCOMP_RESIDENT),
                      INI_TERMCOMP_RESIDENT);
        }
        break;
      case TSKM_SVC_WAIT_NONE:
        // Complete ShutdownWaitSVC
        // Nonresident SVC terminated and started
        p_down->compState |= INI_TERMCOMP_TRANSIENT;
        TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx)",
                    tskm_convTermCompId2Str(INI_TERMCOMP_TRANSIENT),
                    INI_TERMCOMP_TRANSIENT);
        break;
      default:
        // LCOV_EXCL_START 8: As it does not meet the default requirements
        AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
        TSKM_ASSERT(0);
        break;
        // LCOV_EXCL_STOP
    }
  }

  if (tskm_svcsIsWaiting(&p_main->svcs) == TSKM_FALSE &&  // No waiting services
      ((p_down->compState & p_current->nextTransCond)
          == p_current->nextTransCond)) {  // Event completion condition
    if (gstepIsLast(p_down)) {
      tskm_stateTransit(p_main, TSKM_ST_ACCON, TSKM_ST_ACCOFF);
    } else {
      tskm_stateTransit(p_main, TSKM_ST_DOWN, TSKM_ST_DOWN);
    }
  }
}

/*********************************************************
 *        Check and process gradual termination request
 *********************************************************/
TSKM_ERR_t tskm_entryDown_Check_Req(TSKM_MAIN_CTX_t* p_main,
                                    TSKM_GSTEP_t* p_current) {
  uint32_t ii;

  if (0 == p_current->reqNum) {
    EFrameworkunifiedStatus l_eStatus;

    // If there is no gradual termination request, check the transition to the next step.
    l_eStatus = FrameworkunifiedSendSelf(p_main->hApp, TSKM_TRANS_STEP_REQ, 0, NULL);
    if (eFrameworkunifiedStatusOK != l_eStatus) {  // LCOV_EXCL_BR_LINE 5: Checked in death testing, but it is not reflected in the coverage and excluded
      // LCOV_EXCL_START 5: Checked in death testing, but it is not reflected in the coverage and excluded
      AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
      TSKM_ASSERT(0);
      return TSKM_E_NG;
      // LCOV_EXCL_STOP
    }

  } else {
    // Gradual termination request
    for (ii = 0; ii < p_current->reqNum; ii++) {
      TSKM_ERR_t tskmRet;
      TSKM_GSTEP_REQ_INFO_t* p_req = &p_current->reqList[ii];
      TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs,
                                                     p_req->svcId);

      tskmRet = tskm_svcDownRequest(p_svc, p_req);
      if (tskmRet != TSKM_E_OK) {
        TSKM_ASSERT(0);
      }
    }
  }
  return TSKM_E_OK;
}

/*********************************************************
 *        Gradual termination entry process
 *********************************************************/
TSKM_ERR_t tskm_entryDown(TSKM_MAIN_CTX_t* p_main) {
  TSKM_FUNC_IN();

  TSKM_GSTEP_CTX_t* p_down;
  TSKM_GSTEP_t* p_current;

  p_main->state = TSKM_ST_DOWN;
  p_down = gstepGetDownCtx(p_main);
  p_current = gstepGetCurrent(p_down);
  if (p_current == NULL) {  // LCOV_EXCL_BR_LINE 200:p_current can not be null
    // LCOV_EXCL_START 200:p_current can not be null
    AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
    TSKM_ASSERT(0);
    goto ERROR;
    // LCOV_EXCL_STOP
  }
  TSKM_PRINTF(TSKM_LOG_SVCSTATE, "DOWN GSTEP:%d", p_down->gstepIdx);

  if (tskm_entryDown_Check_Req(p_main, p_current) == TSKM_E_NG) {  // LCOV_EXCL_BR_LINE 200:the function of tskm_entryDown_Check_Req can not be TSKM_E_NG at this case // NOLINT(whitespace/line_length)
    // LCOV_EXCL_START 200:tskm_entryDown_Check_Req can not be TSKM_E_NG at this case
    AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
    goto ERROR;
    // LCOV_EXCL_STOP
  }

  if (p_current->nextTransCond) {
    TSKM_PRINTF(TSKM_LOG_STATE, "WAIT COMP:%s(%llx)",
                tskm_convTermCompId2Str(p_current->nextTransCond),
                p_current->nextTransCond);
  }

  TSKM_FUNC_OUT();
  return TSKM_E_OK;

  ERROR: tskm_pf_abort();
  return TSKM_E_NG;
}

/*********************************************************
 *        Gradual termination exit process
 *********************************************************/
TSKM_ERR_t tskm_exitDown(TSKM_MAIN_CTX_t* p_main) {
  TSKM_FUNC_IN();
  TSKM_GSTEP_CTX_t* p_down;

  p_down = gstepGetDownCtx(p_main);

  if (gstepIsLast(p_down)) {
    TSKM_PRINTF(TSKM_LOG_STATE, "DOWN FINISH");
    downFinish(p_main);    // Final process of termination
  }

  changeNextStep(p_down);  // Proceed to the next step

  TSKM_FUNC_OUT();
  return TSKM_E_OK;
}
/*********************************************************
 *        Hander during gradual termination
 *********************************************************/
TSKM_ERR_t tskm_handleDown(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
  TSKM_FUNC_IN();

  switch (p_ev->event) {
    case TSKM_EV_PRI_REP_DOWN_COMP:  // Notificaton for event completion in termination
    {
      TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx) from:%d",
                  tskm_convTermCompId2Str(p_ev->prm.repDownComp.compId),
                  p_ev->prm.repDownComp.compId, p_ev->fromPid);
      TSKM_GSTEP_CTX_t* p_down = gstepGetDownCtx(p_main);
      p_down->compState |= p_ev->prm.repDownComp.compId;
      tryTransNextState(p_main);
    }
      break;
    case TSKM_EV_LCL_CHG_SVC_STATE:  // Service state change
      tryTransNextState(p_main);
      break;
    case TSKM_EV_LCL_REQ_TRANS_STEP:  //Step transition request
      tryTransNextState(p_main);
      break;
    default:
      tskm_handleAccon(p_main, p_ev);
      break;
  }
  TSKM_FUNC_OUT();
  return TSKM_E_OK;
}  // LCOV_EXCL_BR_LINE 10: Final line