diff --git a/fsw/cfe-core/src/es/cfe_es_apps.c b/fsw/cfe-core/src/es/cfe_es_apps.c index ebd7916de..8cb13dd16 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.c +++ b/fsw/cfe-core/src/es/cfe_es_apps.c @@ -822,9 +822,11 @@ int32 CFE_ES_LoadLibrary(CFE_ES_ResourceID_t *LibraryIdPtr, */ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) { - uint32 i; - CFE_ES_AppRecord_t *AppPtr; CFE_ES_AppTableScanState_t *State = (CFE_ES_AppTableScanState_t *)Arg; + uint32 i; + CFE_ES_AppRecord_t *AppPtr; + CFE_ES_ResourceID_t AppTimeoutList[CFE_PLATFORM_ES_MAX_APPLICATIONS]; + uint32 NumAppTimeouts; if (State->PendingAppStateChanges == 0) { @@ -845,6 +847,7 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) * reset the background scan timer to the full value, * and take a snapshot of the the command counter. */ + NumAppTimeouts = 0; State->BackgroundScanTimer = CFE_PLATFORM_ES_APP_SCAN_RATE; State->LastScanCommandCount = CFE_ES_TaskData.CommandCounter; State->PendingAppStateChanges = 0; @@ -888,14 +891,10 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) { AppPtr->ControlReq.AppTimerMsec = 0; - /* - * Temporarily unlock the table, and invoke the - * control request function for this app. - */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - CFE_ES_ProcessControlRequest(AppPtr); - CFE_ES_LockSharedData(__func__,__LINE__); - } /* end if */ + /* Add it to the list to be processed later */ + AppTimeoutList[NumAppTimeouts] = CFE_ES_AppRecordGetID(AppPtr); + ++NumAppTimeouts; + } } else if (AppPtr->AppState == CFE_ES_AppState_RUNNING && AppPtr->ControlReq.AppControlRequest > CFE_ES_RunStatus_APP_RUN) @@ -915,6 +914,22 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) CFE_ES_UnlockSharedData(__func__,__LINE__); + + /* + * Now invoke the CFE_ES_ProcessControlRequest() routine for any app + * which has reached that point. + */ + for ( i = 0; i < NumAppTimeouts; i++ ) + { + /* + * Call CFE_ES_ProcessControlRequest() with a reference to + * the _copies_ of the app record details. (This avoids + * needing to access the global records outside of the lock). + */ + CFE_ES_ProcessControlRequest(AppTimeoutList[i]); + } + + /* * This state machine is considered active if there are any * pending app state changes. Returning "true" will cause this job @@ -932,180 +947,228 @@ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg) ** Purpose: This function will perform the requested control action for an application. **--------------------------------------------------------------------------------------- */ -void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr) +void CFE_ES_ProcessControlRequest(CFE_ES_ResourceID_t AppId) { + CFE_ES_AppRecord_t *AppRecPtr; + uint32 PendingControlReq; + CFE_ES_AppStartParams_t OrigStartParams; + CFE_Status_t CleanupStatus; + CFE_Status_t StartupStatus; + CFE_ES_ResourceID_t NewAppId; + const char *ReqName; + char MessageDetail[48]; + uint16 EventID; + CFE_EVS_EventType_Enum_t EventType; + + /* Init/clear all local state variables */ + ReqName = NULL; + MessageDetail[0] = 0; + EventID = 0; + EventType = 0; + StartupStatus = CFE_SUCCESS; + PendingControlReq = 0; + NewAppId = CFE_ES_RESOURCEID_UNDEFINED; + AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); + memset(&OrigStartParams, 0, sizeof(OrigStartParams)); - int32 Status; - CFE_ES_AppStartParams_t AppStartParams; - CFE_ES_ResourceID_t NewAppId; - /* - ** First get a copy of the Apps Start Parameters - */ - memcpy(&AppStartParams, &(AppRecPtr->StartParams), sizeof(CFE_ES_AppStartParams_t)); + /* + * Take a local snapshot of the important app record data + * This way it becomes private and can be accessed without + * concerns about other threads/tasks, even after the global + * data records are eventually cleared. + */ + CFE_ES_LockSharedData(__func__,__LINE__); - /* - ** Now, find out what kind of Application control is being requested - */ - switch ( AppRecPtr->ControlReq.AppControlRequest ) - { + if (CFE_ES_AppRecordIsMatch(AppRecPtr, AppId)) + { + PendingControlReq = AppRecPtr->ControlReq.AppControlRequest; + OrigStartParams = AppRecPtr->StartParams; + } - case CFE_ES_RunStatus_APP_EXIT: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + CFE_ES_UnlockSharedData(__func__,__LINE__); - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_EXIT_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Exit Application %s Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_EXIT_APP_ERR_EID, CFE_EVS_EventType_ERROR, - "Exit Application %s Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + /* + * All control requests start by deleting the app/task and + * all associated resources. + * + * The reload/restart requests will start it again, and it gets + * a new appID. For other requests it just leaves it deleted. + * + * Note that Cleanup can fail for a variety of reasons, including + * situations where e.g. a task ID had become stale because the task + * already exited itself. In most cases these are minor errors and + * reflect problems with the consistency of the old app record. + * + * Even when this happens the cleanup should still do its best effort + * to release all relevant global data entries. So it should not + * prevent starting the new app, if a restart/reload is indicated. + */ + CleanupStatus = CFE_ES_CleanUpApp(AppId); - case CFE_ES_RunStatus_APP_ERROR: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + /* + * Attempt to restart the app if the request indicated to do so, + * regardless of the CleanupStatus. + */ + if ( PendingControlReq == CFE_ES_RunStatus_SYS_RESTART || + PendingControlReq == CFE_ES_RunStatus_SYS_RELOAD ) + { + StartupStatus = CFE_ES_AppCreate(&NewAppId, + OrigStartParams.FileName, + OrigStartParams.EntryPoint, + OrigStartParams.Name, + OrigStartParams.Priority, + OrigStartParams.StackSize, + OrigStartParams.ExceptionAction); + } - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_ERREXIT_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Exit Application %s on Error Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_ERREXIT_APP_ERR_EID, CFE_EVS_EventType_ERROR, - "Exit Application %s on Error Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + /* + * Determine the event ID associated with the control request, + * which indicates the success/failure of the operation and + * any other relevant detail. + * + * Note that the specific event ID that gets generated is the only + * other difference between all these control request types. + */ + switch ( PendingControlReq ) + { + case CFE_ES_RunStatus_APP_EXIT: + ReqName = "Exit"; + if (CleanupStatus != CFE_SUCCESS) + { + /* error event for this request */ + EventID = CFE_ES_EXIT_APP_ERR_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_EXIT_APP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_DELETE: - /* - ** Kill the app, and dont restart it - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + case CFE_ES_RunStatus_APP_ERROR: + ReqName = "Exit"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_ERREXIT_APP_ERR_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_ERREXIT_APP_INF_EID; + } + break; - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_STOP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Stop Application %s Completed.",AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_STOP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Stop Application %s Failed: CleanUpApp Error 0x%08X.",AppStartParams.Name, (unsigned int)Status); - } - break; + case CFE_ES_RunStatus_SYS_DELETE: + ReqName = "Stop"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_STOP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_STOP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_RESTART: - /* - ** Kill the app - */ - Status = CFE_ES_CleanUpApp(AppRecPtr); + case CFE_ES_RunStatus_SYS_RESTART: + ReqName = "Restart"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RESTART_APP_ERR4_EID; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RESTART_APP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_RESTART_APP_INF_EID; + } + break; - if ( Status == CFE_SUCCESS ) - { - /* - ** And start it back up again - */ - Status = CFE_ES_AppCreate(&NewAppId, (char *)AppStartParams.FileName, - (char *)AppStartParams.EntryPoint, - (char *)AppStartParams.Name, - AppStartParams.Priority, - AppStartParams.StackSize, - AppStartParams.ExceptionAction); - - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Restart Application %s Completed.", AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Restart Application %s Failed: AppCreate Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - } - else - { - CFE_EVS_SendEvent(CFE_ES_RESTART_APP_ERR4_EID, CFE_EVS_EventType_ERROR, - "Restart Application %s Failed: CleanUpApp Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - break; + case CFE_ES_RunStatus_SYS_RELOAD: + ReqName = "Reload"; + if ( CleanupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RELOAD_APP_ERR4_EID; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* error event for this request */ + EventID = CFE_ES_RELOAD_APP_ERR3_EID; + } + else + { + /* success event for this request */ + EventID = CFE_ES_RELOAD_APP_INF_EID; + } + break; - case CFE_ES_RunStatus_SYS_RELOAD: - /* - ** Kill the app + /* + * These two cases below should never occur so they are always + * reported as errors, but the CFE_ES_CleanUpApp() should hopefully + * have fixed it either way. */ - Status = CFE_ES_CleanUpApp(AppRecPtr); - - if ( Status == CFE_SUCCESS ) - { - /* - ** And start it back up again - */ - Status = CFE_ES_AppCreate(&NewAppId, (char *)AppStartParams.FileName, - (char *)AppStartParams.EntryPoint, - (char *)AppStartParams.Name, - AppStartParams.Priority, - AppStartParams.StackSize, - AppStartParams.ExceptionAction); - if ( Status == CFE_SUCCESS ) - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_INF_EID, CFE_EVS_EventType_INFORMATION, - "Reload Application %s Completed.", AppStartParams.Name); - } - else - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_ERR3_EID, CFE_EVS_EventType_ERROR, - "Reload Application %s Failed: AppCreate Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - } - else - { - CFE_EVS_SendEvent(CFE_ES_RELOAD_APP_ERR4_EID, CFE_EVS_EventType_ERROR, - "Reload Application %s Failed: CleanUpApp Error 0x%08X.", AppStartParams.Name, (unsigned int)Status); - } - - break; - - case CFE_ES_RunStatus_SYS_EXCEPTION: - - CFE_EVS_SendEvent(CFE_ES_PCR_ERR1_EID, CFE_EVS_EventType_ERROR, - "ES_ProcControlReq: Invalid State (EXCEPTION) Application %s.", - AppStartParams.Name); - /* - * Bug #58: This message/event keeps repeating itself indefinitely. - * - * Change the request state to DELETE so the next scan will clean - * up this table entry. - */ - AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; - break; - - default: + case CFE_ES_RunStatus_SYS_EXCEPTION: + ReqName = "ES_ProcControlReq: Invalid State"; + EventID = CFE_ES_PCR_ERR1_EID; + snprintf(MessageDetail, sizeof(MessageDetail), "EXCEPTION"); + break; - CFE_EVS_SendEvent(CFE_ES_PCR_ERR2_EID, CFE_EVS_EventType_ERROR, - "ES_ProcControlReq: Unknown State ( %d ) Application %s.", - (int)AppRecPtr->ControlReq.AppControlRequest, AppStartParams.Name); + default: + ReqName = "ES_ProcControlReq: Unknown State"; + EventID = CFE_ES_PCR_ERR2_EID; + snprintf(MessageDetail, sizeof(MessageDetail), "( %lu )", + (unsigned long)PendingControlReq); + break; + } - /* - * Bug #58: This message/event keeps repeating itself indefinitely. - * - * Change the request state to DELETE so the next scan will clean - * up this table entry. - */ - AppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; - break; + if (EventID != 0 && ReqName != NULL) + { + if ( MessageDetail[0] != 0 ) + { + /* Detail message already set, assume it is an error event */ + EventType = CFE_EVS_EventType_ERROR; + } + else if ( StartupStatus != CFE_SUCCESS ) + { + /* Make detail message for event containing startup error code */ + EventType = CFE_EVS_EventType_ERROR; + snprintf(MessageDetail, sizeof(MessageDetail), + "Failed: AppCreate Error 0x%08X.",(unsigned int)StartupStatus); + } + else if ( CleanupStatus != CFE_SUCCESS ) + { + /* Make detail message for event containing cleanup error code */ + EventType = CFE_EVS_EventType_ERROR; + snprintf(MessageDetail, sizeof(MessageDetail), + "Failed: CleanUpApp Error 0x%08X.",(unsigned int)CleanupStatus); + } + else if (CFE_ES_ResourceID_IsDefined(NewAppId)) + { + /* Record success message for event where app is restarted */ + EventType = CFE_EVS_EventType_INFORMATION; + snprintf(MessageDetail, sizeof(MessageDetail), "Completed, AppID=%lu", + CFE_ES_ResourceID_ToInteger(NewAppId)); + } + else + { + /* Record success message for event */ + EventType = CFE_EVS_EventType_INFORMATION; + snprintf(MessageDetail, sizeof(MessageDetail), "Completed."); + } - } + CFE_EVS_SendEvent(EventID, EventType, "%s Application %s %s", + ReqName, OrigStartParams.Name, MessageDetail); + } } /* End Function */ @@ -1116,154 +1179,248 @@ void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr) ** Purpose: Delete an application by cleaning up all of it's resources. **--------------------------------------------------------------------------------------- */ -int32 CFE_ES_CleanUpApp(CFE_ES_AppRecord_t *AppRecPtr) +int32 CFE_ES_CleanUpApp(CFE_ES_ResourceID_t AppId) { - uint32 i; - int32 Status; - CFE_ES_ResourceID_t MainTaskId; - CFE_ES_ResourceID_t CurrTaskId; - int32 ReturnCode = CFE_SUCCESS; - CFE_ES_TaskRecord_t *TaskRecPtr; - CFE_ES_MemPoolRecord_t *MemPoolRecPtr; - CFE_ES_MemHandle_t PoolId; - CFE_ES_ResourceID_t AppId; + uint32 i; + int32 Status; + int32 ReturnCode; + CFE_ES_ResourceID_t TaskList[OS_MAX_TASKS]; + CFE_ES_MemHandle_t PoolList[CFE_PLATFORM_ES_MAX_MEMORY_POOLS]; + osal_id_t ModuleId; + uint32 NumTasks; + uint32 NumPools; + CFE_ES_AppRecord_t *AppRecPtr; + CFE_ES_TaskRecord_t *TaskRecPtr; + CFE_ES_MemPoolRecord_t *MemPoolRecPtr; - /* - * Retrieve the abstract AppID for calling cleanup - * routine in _other_ modules. - */ - AppId = CFE_ES_AppRecordGetID(AppRecPtr); - /* - ** Call the Table Clean up function - */ -#ifndef EXCLUDE_CFE_TBL - CFE_TBL_CleanUpApp(AppId); -#endif - /* - ** Call the Software Bus clean up function - */ - CFE_SB_CleanUpApp(AppId); + NumTasks = 0; + NumPools = 0; + ModuleId = OS_OBJECT_ID_UNDEFINED; + ReturnCode = CFE_SUCCESS; - /* - ** Call the TIME Clean up function - */ - CFE_TIME_CleanUpApp(AppId); + AppRecPtr = CFE_ES_LocateAppRecordByID(AppId); - /* - ** Call the EVS Clean up function - */ - Status = CFE_EVS_CleanUpApp(AppId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Call to CFE_EVS_CleanUpApp returned Error: 0x%08X\n",(unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } + /* + * Collect a list of resources previously owned by this app, which + * must be done while the global data is locked. + */ + CFE_ES_LockSharedData(__func__,__LINE__); + if (CFE_ES_AppRecordIsMatch(AppRecPtr, AppId)) + { + if (AppRecPtr->Type == CFE_ES_AppType_EXTERNAL) + { + CFE_ES_Global.RegisteredExternalApps--; - /* - ** Delete the ES Resources - */ - CFE_ES_LockSharedData(__func__,__LINE__); + /* + * Get the Module ID, if it was an external app + * + * (this will be OS_OBJECT_ID_UNDEFINED if it was not loaded dynamically) + */ + ModuleId = AppRecPtr->StartParams.ModuleId; + } - /* - ** Get Main Task ID - */ - MainTaskId = AppRecPtr->MainTaskId; + /* + * Collect all tasks associated with this app + */ + TaskRecPtr = CFE_ES_Global.TaskTable; + for ( i = 0; i < OS_MAX_TASKS; i++ ) + { + if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) && + CFE_ES_ResourceID_Equal(TaskRecPtr->AppId, AppId)) + { + TaskList[NumTasks] = CFE_ES_TaskRecordGetID(TaskRecPtr); - /* - ** Delete any child tasks associated with this app - */ - TaskRecPtr = CFE_ES_Global.TaskTable; - for ( i = 0; i < OS_MAX_TASKS; i++ ) - { - /* delete only CHILD tasks - not the MainTaskId, which will be deleted later (below) */ - if ( CFE_ES_TaskRecordIsUsed(TaskRecPtr) && - CFE_ES_ResourceID_Equal(TaskRecPtr->AppId, AppId)) - { - CurrTaskId = CFE_ES_TaskRecordGetID(TaskRecPtr); - if (!CFE_ES_ResourceID_Equal(CurrTaskId, MainTaskId)) - { - Status = CFE_ES_CleanupTaskResources(CurrTaskId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(CurrTaskId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - } /* end if */ - } + /* Store the main task ID at index 0 (swap with whatever was there) */ + if (CFE_ES_ResourceID_Equal(TaskList[NumTasks], AppRecPtr->MainTaskId) && + NumTasks != 0) + { + TaskList[NumTasks] = TaskList[0]; + TaskList[0] = AppRecPtr->MainTaskId; + } - ++TaskRecPtr; - } /* end for */ + /* Mark record for removal */ + CFE_ES_TaskRecordSetUsed(TaskRecPtr, CFE_ES_RESOURCEID_RESERVED); + ++NumTasks; + } - /* - ** Delete all of the OS resources, close files, and delete the main task - */ - Status = CFE_ES_CleanupTaskResources(MainTaskId); - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(MainTaskId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; + ++TaskRecPtr; + } /* end for */ - } + CFE_ES_Global.RegisteredTasks -= NumTasks; - /* - ** Remove the app from the AppTable - */ - if ( AppRecPtr->Type == CFE_ES_AppType_EXTERNAL ) - { - /* - ** Unload the module only if it is an external app - */ - Status = OS_ModuleUnload(AppRecPtr->StartParams.ModuleId); - if ( Status == OS_ERROR ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: Module (ID:0x%08lX) Unload failed. RC=0x%08X\n", - OS_ObjectIdToInteger(AppRecPtr->StartParams.ModuleId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - CFE_ES_Global.RegisteredExternalApps--; - } + /* + * Collect memory pools associated with this app + */ + MemPoolRecPtr = CFE_ES_Global.MemPoolTable; + for ( i = 0; i < CFE_PLATFORM_ES_MAX_MEMORY_POOLS; i++ ) + { + if ( CFE_ES_MemPoolRecordIsUsed(MemPoolRecPtr) && + CFE_ES_ResourceID_Equal(MemPoolRecPtr->OwnerAppID, AppId)) + { + PoolList[NumPools] = CFE_ES_MemPoolRecordGetID(MemPoolRecPtr); + ++NumPools; + } - CFE_ES_AppRecordSetFree(AppRecPtr); + ++MemPoolRecPtr; + } /* end for */ - /* - ** Delete any memory pools associated with this app - */ - MemPoolRecPtr = CFE_ES_Global.MemPoolTable; - for ( i = 0; i < CFE_PLATFORM_ES_MAX_MEMORY_POOLS; i++ ) - { - if ( CFE_ES_MemPoolRecordIsUsed(MemPoolRecPtr) && - CFE_ES_ResourceID_Equal(MemPoolRecPtr->OwnerAppID, AppId)) - { - PoolId = CFE_ES_MemPoolRecordGetID(MemPoolRecPtr); + /* + * Set the record to RESERVED. + * + * This prevents reallocation of this slot while the remainder + * of resources are freed. + */ + CFE_ES_AppRecordSetUsed(AppRecPtr, CFE_ES_RESOURCEID_RESERVED); - /* - * This needs to release the lock first because - * CFE_ES_PoolDelete acquires the lock. - */ - CFE_ES_UnlockSharedData(__func__, __LINE__); - Status = CFE_ES_PoolDelete(PoolId); - CFE_ES_LockSharedData(__func__, __LINE__); + ReturnCode = CFE_SUCCESS; + } + else + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: AppID %lu is not valid for deletion\n", + CFE_ES_ResourceID_ToInteger(AppId)); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } - if ( Status != CFE_SUCCESS ) - { - CFE_ES_SysLogWrite_Unsync("CFE_ES_MemPoolCleanupApp: delete pool %lu returned Error: 0x%08X\n", - CFE_ES_ResourceID_ToInteger(PoolId), (unsigned int)Status); - ReturnCode = CFE_ES_APP_CLEANUP_ERR; - } - } + CFE_ES_UnlockSharedData(__func__, __LINE__); - ++MemPoolRecPtr; - } /* end for */ + if (ReturnCode != CFE_SUCCESS) + { + return ReturnCode; + } + /* + * Now actually delete all the resources associated with the task. + * + * Most of this involves calling into other subsystems, so it is + * done while the ES global data is UNLOCKED to avoid holding more + * than one lock at a time. + */ - CFE_ES_UnlockSharedData(__func__,__LINE__); + /* + ** Call the Table Clean up function + */ + CFE_TBL_CleanUpApp(AppId); - return(ReturnCode); + /* + ** Call the Software Bus clean up function + */ + CFE_SB_CleanUpApp(AppId); + + /* + ** Call the TIME Clean up function + */ + CFE_TIME_CleanUpApp(AppId); + + /* + ** Call the EVS Clean up function + */ + Status = CFE_EVS_CleanUpApp(AppId); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Call to CFE_EVS_CleanUpApp returned Error: 0x%08X\n",(unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + + /* + * Delete all tasks. + * + * Note that the main task is always positioned at index 0 in this list. + * + * This iterates the list in reverse order, such that the child + * tasks are deleted first (in any order) and main task is deleted last. + */ + i = NumTasks; + while (i > 0) + { + --i; + Status = CFE_ES_CleanupTaskResources(TaskList[i]); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: CleanUpTaskResources for Task ID:%lu returned Error: 0x%08X\n", + CFE_ES_ResourceID_ToInteger(TaskList[i]), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + * Delete all mem pools. + */ + for (i=0; i < NumPools; ++i) + { + Status = CFE_ES_PoolDelete(PoolList[i]); + if ( Status != CFE_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_MemPoolCleanupApp: delete pool %lu returned Error: 0x%08X\n", + CFE_ES_ResourceID_ToInteger(PoolList[i]), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + ** Unload the module, if applicable + */ + if ( OS_ObjectIdDefined(ModuleId) ) + { + /* + ** Unload the module only if it is an external app + */ + Status = OS_ModuleUnload(ModuleId); + if ( Status != OS_SUCCESS ) + { + CFE_ES_WriteToSysLog("CFE_ES_CleanUpApp: Module (ID:0x%08lX) Unload failed. RC=0x%08X\n", + OS_ObjectIdToInteger(ModuleId), (unsigned int)Status); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } + } + + /* + * Finally, re-acquire the ES lock and set all + * table entries free for re-use. + */ + CFE_ES_LockSharedData(__func__,__LINE__); + +#ifdef jphfix + /* + * This just confirms that the main task ID associated with this app was properly + * located and deleted during the previous process. + * + * If not, display a log message about it - this indicates table corruption or a + * bug with the record keeping. + */ + if (NumTasks == 0 || !CFE_ES_ResourceID_Equal(TaskList[0], AppRecPtr->MainTaskId)) + { + CFE_ES_SysLogWrite_Unsync("CFE_ES_CleanUpApp: MainTask ID:%lu not found when deleting AppID %lu\n", + CFE_ES_ResourceID_ToInteger(AppRecPtr->MainTaskId), CFE_ES_ResourceID_ToInteger(AppId)); + ReturnCode = CFE_ES_APP_CLEANUP_ERR; + } +#endif + + /* + * Free all task records. + */ + for (i=0; i < NumTasks; ++i) + { + TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskList[i]); + if (CFE_ES_TaskRecordIsMatch(TaskRecPtr, CFE_ES_RESOURCEID_RESERVED)) + { + CFE_ES_TaskRecordSetFree(TaskRecPtr); + } + } + + /* + * Now finally delete the record and allow re-use of the slot. + */ + if (CFE_ES_AppRecordIsMatch(AppRecPtr, CFE_ES_RESOURCEID_RESERVED)) + { + CFE_ES_AppRecordSetFree(AppRecPtr); + } + + CFE_ES_UnlockSharedData(__func__,__LINE__); + + return(ReturnCode); } /* end function */ @@ -1387,13 +1544,14 @@ void CFE_ES_CleanupObjectCallback(osal_id_t ObjectId, void *arg) ** Name: CFE_ES_CleanupTaskResources ** ** Purpose: Clean up the OS resources associated with an individual Task +** Note: This is called when the ES global is UNLOCKED - so it should not touch +** any ES global data structures. It should only clean up at the OSAL level. **--------------------------------------------------------------------------------------- */ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) { CFE_ES_CleanupState_t CleanState; int32 Result; - CFE_ES_TaskRecord_t *TaskRecPtr; osal_id_t OsalId; /* Get the Task ID for calling OSAL APIs (convert type) */ @@ -1424,16 +1582,15 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) CleanState.DeletedObjects = 0; } - /* - * Locate the ES Task table entry - */ - TaskRecPtr = CFE_ES_LocateTaskRecordByID(TaskId); - /* ** Delete the task itself + ** + ** Note, if the task self exited, then the ID becomes invalid. + ** In this case the OS_ERR_INVALID_ID status is returned, but + ** that is OK, there is nothing else needed to do. */ Result = OS_TaskDelete(OsalId); - if (Result == OS_SUCCESS) + if (Result == OS_SUCCESS || Result == OS_ERR_INVALID_ID) { Result = CleanState.OverallStatus; if (Result == CFE_SUCCESS && CleanState.FoundObjects > 0) @@ -1447,15 +1604,6 @@ int32 CFE_ES_CleanupTaskResources(CFE_ES_ResourceID_t TaskId) Result = CFE_ES_TASK_DELETE_ERR; } - /* - ** Invalidate ES Task Table entry - */ - if (TaskRecPtr != NULL) - { - CFE_ES_TaskRecordSetFree(TaskRecPtr); - } - - CFE_ES_Global.RegisteredTasks--; return(Result); } diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index fa29774b4..4cf2c11bc 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -199,12 +199,12 @@ bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg); /* ** Perform the requested control action for an application */ -void CFE_ES_ProcessControlRequest(CFE_ES_AppRecord_t *AppRecPtr); +void CFE_ES_ProcessControlRequest(CFE_ES_ResourceID_t AppId); /* ** Clean up all app resources and delete it */ -int32 CFE_ES_CleanUpApp(CFE_ES_AppRecord_t *AppRecPtr); +int32 CFE_ES_CleanUpApp(CFE_ES_ResourceID_t AppId); /* ** Clean up all Task resources and detete the task diff --git a/fsw/cfe-core/src/inc/cfe_es_events.h b/fsw/cfe-core/src/inc/cfe_es_events.h index c7bad610e..8b0f4b432 100644 --- a/fsw/cfe-core/src/inc/cfe_es_events.h +++ b/fsw/cfe-core/src/inc/cfe_es_events.h @@ -167,8 +167,8 @@ **/ #define CFE_ES_RESTART_APP_DBG_EID 9 -/** \brief 'Restart Application \%s Completed.' -** \event 'Restart Application \%s Completed.' +/** \brief 'Restart Application \%s Completed, AppID=%lu' +** \event 'Restart Application \%s Completed, AppID=%lu' ** ** \par Type: INFORMATION ** @@ -178,7 +178,8 @@ ** That was started when the \link #CFE_ES_RESTART_APP_CC Restart Application command \endlink ** was issued. ** -** The \c 's' field identifies the name of the Application that was reloaded. +** The \c 's' field identifies the name of the Application that was restarted, and +** the %lu field identifies the new Application ID */ #define CFE_ES_RESTART_APP_INF_EID 10 @@ -202,8 +203,8 @@ #define CFE_ES_RELOAD_APP_DBG_EID 11 -/** \brief 'Reload Application \%s Completed.' -** \event 'Reload Application \%s Completed.' +/** \brief 'Reload Application \%s Completed, AppID=%lu' +** \event 'Reload Application \%s Completed, AppID=%lu' ** ** \par Type: INFORMATION ** @@ -213,7 +214,8 @@ ** That was started when the \link #CFE_ES_RELOAD_APP_CC Restart Application command \endlink ** was issued. ** -** The \c 's' field identifies the name of the Application that was reloaded. +** The \c 's' field identifies the name of the Application that was reloaded, and +** the %lu field identifies the new Application ID */ #define CFE_ES_RELOAD_APP_INF_EID 12 diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index fe99f690e..3a134cf50 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -1437,8 +1437,7 @@ void TestApps(void) CFE_ES_RunAppTableScan(0, &CFE_ES_TaskData.BackgroundAppScanState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID) && - UtAppRecPtr->ControlReq.AppTimerMsec == 0 && - UtAppRecPtr->ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_DELETE, + UtAppRecPtr->ControlReq.AppTimerMsec == 0, "CFE_ES_RunAppTableScan", "Waiting; process control request"); @@ -1466,7 +1465,6 @@ void TestApps(void) CFE_ES_RunAppTableScan(0, &CFE_ES_TaskData.BackgroundAppScanState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID) && - UtAppRecPtr->ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_DELETE && UtAppRecPtr->ControlReq.AppTimerMsec == 0, "CFE_ES_RunAppTableScan", "Stopped; process control request"); @@ -1490,7 +1488,8 @@ void TestApps(void) ES_ResetUnitTest(); ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); UtAppRecPtr->ControlReq.AppControlRequest = 0x12345; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR2_EID), "CFE_ES_ProcessControlRequest", @@ -1512,7 +1511,8 @@ void TestApps(void) OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_EXIT; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_EXIT_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1526,7 +1526,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_EXIT; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_EXIT_APP_ERR_EID), "CFE_ES_ProcessControlRequest", @@ -1541,7 +1542,8 @@ void TestApps(void) CFE_ES_RunStatus_SYS_DELETE; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_STOP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1556,7 +1558,8 @@ void TestApps(void) CFE_ES_RunStatus_SYS_RESTART; UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_ERR4_EID), "CFE_ES_ProcessControlRequest", @@ -1571,7 +1574,8 @@ void TestApps(void) CFE_ES_RunStatus_SYS_RESTART; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1586,7 +1590,8 @@ void TestApps(void) CFE_ES_RunStatus_SYS_RELOAD; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_ERR4_EID), "CFE_ES_ProcessControlRequest", @@ -1601,7 +1606,8 @@ void TestApps(void) CFE_ES_RunStatus_SYS_RELOAD; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_ERR3_EID), "CFE_ES_ProcessControlRequest", @@ -1625,7 +1631,8 @@ void TestApps(void) OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_ERROR; - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_ERREXIT_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1640,7 +1647,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_ERROR; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_ERREXIT_APP_ERR_EID), "CFE_ES_ProcessControlRequest", @@ -1662,7 +1670,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_DELETE; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_STOP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1684,7 +1693,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RESTART; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RESTART_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1706,7 +1716,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_RELOAD; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_RELOAD_APP_INF_EID), "CFE_ES_ProcessControlRequest", @@ -1730,7 +1741,8 @@ void TestApps(void) UtAppRecPtr->ControlReq.AppControlRequest = CFE_ES_RunStatus_SYS_EXCEPTION; OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); - CFE_ES_ProcessControlRequest(UtAppRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); + CFE_ES_ProcessControlRequest(Id); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_PCR_ERR1_EID), "CFE_ES_ProcessControlRequest", @@ -1800,8 +1812,9 @@ void TestApps(void) OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetForceFail(UT_KEY(OS_TaskDelete), OS_ERROR); UT_SetForceFail(UT_KEY(OS_close), OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Task OS delete and close failure"); @@ -1814,8 +1827,9 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, NULL, NULL); ES_UT_SetupForOSCleanup(); UT_SetDeferredRetcode(UT_KEY(OS_MutSemDelete), 1, OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Task mutex delete failure"); @@ -1826,8 +1840,9 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(OS_ModuleUnload), 1, OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Module unload failure"); @@ -1838,8 +1853,9 @@ void TestApps(void) ES_UT_SetupSingleAppId(CFE_ES_AppType_EXTERNAL, CFE_ES_AppState_RUNNING, NULL, &UtAppRecPtr, NULL); OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); UT_SetDeferredRetcode(UT_KEY(CFE_EVS_CleanUpApp), 1, -1); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "EVS application cleanup failure"); @@ -2015,8 +2031,9 @@ void TestApps(void) OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, NULL, NULL); /* Associate a child task with the app to be deleted */ ES_UT_SetupChildTaskId(UtAppRecPtr, NULL, NULL); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS, + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS, "CFE_ES_CleanUpApp", "Main task ID matches task ID, nominal"); UT_Report(__FILE__, __LINE__, @@ -2038,8 +2055,9 @@ void TestApps(void) ES_UT_SetupMemPoolId(&UtPoolRecPtr); UtPoolRecPtr->OwnerAppID = CFE_ES_AppRecordGetID(UtAppRecPtr); UtPoolRecPtr->PoolID = CFE_ES_ResourceID_FromInteger(99999); /* Mismatch */ + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Mem Pool delete error"); UT_Report(__FILE__, __LINE__, @@ -2065,12 +2083,13 @@ void TestApps(void) UtAppRecPtr->MainTaskId = CFE_ES_TaskRecordGetID(UtTaskRecPtr); UT_SetForceFail(UT_KEY(OS_TaskDelete), OS_ERROR); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_ES_APP_CLEANUP_ERR, + CFE_ES_CleanUpApp(Id) == CFE_ES_APP_CLEANUP_ERR, "CFE_ES_CleanUpApp", "Main task ID doesn't match task ID, CFE_ES_APP_CLEANUP_ERR"); UT_Report(__FILE__, __LINE__, - !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), + CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), "CFE_ES_CleanUpApp", "Main task ID doesn't match task ID, second task unchanged"); @@ -2087,14 +2106,15 @@ void TestApps(void) /* switch the main task association (makes it wrong) */ UtAppRecPtr->MainTaskId = CFE_ES_TaskRecordGetID(UtTaskRecPtr); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS, + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS, "CFE_ES_CleanUpApp", "Application ID mismatch; core application"); UT_Report(__FILE__, __LINE__, - !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), + CFE_ES_TaskRecordIsUsed(UtTaskRecPtr), "CFE_ES_CleanUpApp", "Application ID mismatch; core application"); @@ -2113,8 +2133,9 @@ void TestApps(void) OS_ModuleLoad(&UtAppRecPtr->StartParams.ModuleId, "UT", "ut-module"); + Id = CFE_ES_AppRecordGetID(UtAppRecPtr); UT_Report(__FILE__, __LINE__, - CFE_ES_CleanUpApp(UtAppRecPtr) == CFE_SUCCESS && + CFE_ES_CleanUpApp(Id) == CFE_SUCCESS && !CFE_ES_TaskRecordIsUsed(UtTaskRecPtr) && CFE_ES_Global.RegisteredExternalApps == 0, "CFE_ES_CleanUpApp",