|
@@ -3,6 +3,13 @@
|
|
|
|
|
|
#include <vector>
|
|
|
#include <memory>
|
|
|
+#include <thread>
|
|
|
+#include <chrono>
|
|
|
+#include <algorithm>
|
|
|
+
|
|
|
+#include "iniutil.h"
|
|
|
+
|
|
|
+#include "SpBase.h"
|
|
|
|
|
|
#define ISSUCCEEDED(hr) ((hr) == Error_Succeed)
|
|
|
#define FAILURED(hr) (!(ISSUCCEEDED(hr)))
|
|
@@ -20,14 +27,15 @@ enum EntityBootStep
|
|
|
CoreBoot,
|
|
|
SafeLoad,
|
|
|
IEBrowser,
|
|
|
- Operating
|
|
|
+ Operating,
|
|
|
+ NotConfigInit,
|
|
|
+ NotConfigSecond
|
|
|
};
|
|
|
|
|
|
-class BootManager;
|
|
|
-
|
|
|
struct EntityBootInfo
|
|
|
{
|
|
|
CSimpleStringA entityName;
|
|
|
+ CSimpleStringA cmdLine;
|
|
|
EntityBootType bootType;
|
|
|
ErrorCodeEnum bootResult;
|
|
|
EntityBootInfo(const char* name, EntityBootType type)
|
|
@@ -38,6 +46,8 @@ struct EntityBootInfo
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+struct StartEntityOperation;
|
|
|
+
|
|
|
struct BootStep
|
|
|
{
|
|
|
CSimpleStringA strSectionName;
|
|
@@ -47,12 +57,32 @@ struct BootStep
|
|
|
BootStep(const char* stepName) :strSectionName(stepName) {}
|
|
|
virtual ~BootStep() {}
|
|
|
|
|
|
- ErrorCodeEnum LoadConfig(const CSimpleStringA& configPath);
|
|
|
+ static ErrorCodeEnum WaitForAsyncEntitStartOperation(std::vector<StartEntityOperation*>& entityList);
|
|
|
+
|
|
|
+ ErrorCodeEnum LoadConfig(const CSimpleStringA& configPath)
|
|
|
+ {
|
|
|
+ array_header_t* keys = inifile_read_section_key_all(configPath, strSectionName);
|
|
|
+ if (!keys || array_empty(keys)) {
|
|
|
+ return Error_NotExist;
|
|
|
+ }
|
|
|
+
|
|
|
+ entityList.clear();
|
|
|
+
|
|
|
+ for (size_t i = 0; i < keys->nelts; ++i) {
|
|
|
+ char* entityName = ARRAY_IDX(keys, i, char*);
|
|
|
+ int bootType = inifile_read_int(configPath, strSectionName, entityName, 0);
|
|
|
+ Dbg("boot type info: %s=%d", entityName, bootType);
|
|
|
+ EntityBootInfo entityBootInfo{ entityName, static_cast<EntityBootType>(bootType) };
|
|
|
+ entityList.push_back(entityBootInfo);
|
|
|
+ }
|
|
|
+ toolkit_array_free2(keys);
|
|
|
+ return Error_Succeed;
|
|
|
+ }
|
|
|
bool HasEntity() const
|
|
|
{
|
|
|
return(!entityList.empty());
|
|
|
}
|
|
|
- ErrorCodeEnum StartStartupEntities(BootManager* pTrigger);
|
|
|
+ ErrorCodeEnum StartStartupEntities(CEntityBase* pTrigger);
|
|
|
};
|
|
|
|
|
|
struct CoreBootStep : public BootStep
|
|
@@ -87,6 +117,22 @@ struct OperatingStep : public BootStep
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+struct TerminalDeployStep : public BootStep
|
|
|
+{
|
|
|
+ TerminalDeployStep(const CSimpleStringA& sectionPosix)
|
|
|
+ : BootStep(CSimpleStringA("TerminalDeploy"))
|
|
|
+ {
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+struct TerminalDeploySecondStep : public BootStep
|
|
|
+{
|
|
|
+ TerminalDeploySecondStep(const CSimpleStringA& sectionPosix)
|
|
|
+ : BootStep(CSimpleStringA("TerminalDeploy.") + sectionPosix)
|
|
|
+ {
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
struct StartEntityBaseContext : public IReleasable
|
|
|
{
|
|
|
CEntityBase* theEntity;
|
|
@@ -110,7 +156,7 @@ struct StartEntitySyncContenxt : public StartEntityBaseContext
|
|
|
{
|
|
|
ErrorCodeEnum result(Error_Succeed);
|
|
|
CSmartPointer<IAsynWaitSp> spWait;
|
|
|
- result = StartEntity(entityInfo->entityName, nullptr, spWait);
|
|
|
+ result = StartEntity(entityInfo->entityName, entityInfo->cmdLine, spWait);
|
|
|
if (ISSUCCEEDED(result) && spWait != nullptr) {
|
|
|
result = spWait->WaitAnswer(60 * 1000);
|
|
|
}
|
|
@@ -124,7 +170,7 @@ struct StartEntityIgnoreContenxt : public StartEntityBaseContext
|
|
|
ErrorCodeEnum BootEntity(const EntityBootInfo* entityInfo)
|
|
|
{
|
|
|
CSmartPointer<IAsynWaitSp> spWait;
|
|
|
- StartEntity(entityInfo->entityName, nullptr, spWait);
|
|
|
+ StartEntity(entityInfo->entityName, entityInfo->cmdLine, spWait);
|
|
|
if (spWait != nullptr) {
|
|
|
spWait->WaitAnswer(100);
|
|
|
}
|
|
@@ -162,7 +208,7 @@ struct StartEntityAsyncContenxt : public StartEntityBaseContext, public ICallbac
|
|
|
ErrorCodeEnum result(Error_Succeed);
|
|
|
CSmartPointer<IAsynWaitSp> spWait;
|
|
|
theFinishedState = Pending;
|
|
|
- result = StartEntity(entityInfo->entityName, nullptr, spWait);
|
|
|
+ result = StartEntity(entityInfo->entityName, entityInfo->cmdLine, spWait);
|
|
|
if (ISSUCCEEDED(result) && spWait != nullptr) {
|
|
|
spWait->SetCallback(this, nullptr);
|
|
|
result = Error_Pending;
|
|
@@ -214,4 +260,68 @@ struct StartEntityOperation
|
|
|
EntityBootInfo& entInfo;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+ErrorCodeEnum BootStep::WaitForAsyncEntitStartOperation(std::vector<StartEntityOperation*>& entityList)
|
|
|
+{
|
|
|
+ LOG_FUNCTION();
|
|
|
+
|
|
|
+ ErrorCodeEnum result = Error_Succeed;
|
|
|
+ for (; !entityList.empty();) {
|
|
|
+ auto finishedInstance = find_if(entityList.begin(), entityList.end()
|
|
|
+ , [](StartEntityOperation* operation) {
|
|
|
+ return operation->IsDone();
|
|
|
+ });
|
|
|
+ if (finishedInstance != entityList.end()) {
|
|
|
+ StartEntityOperation* operation = *finishedInstance;
|
|
|
+ entityList.erase(finishedInstance);
|
|
|
+ auto& entity = operation->entInfo;
|
|
|
+ if (FAILURED(entity.bootResult)) {
|
|
|
+ result = entity.bootResult;
|
|
|
+ }
|
|
|
+ delete operation;
|
|
|
+ } else {
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ErrorCodeEnum BootStep::StartStartupEntities(CEntityBase* pTrigger)
|
|
|
+{
|
|
|
+ ErrorCodeEnum result = Error_Succeed;
|
|
|
+ if (HasEntity()) {
|
|
|
+ std::vector <StartEntityOperation*> pendingEntiList;
|
|
|
+ for (auto& entity : entityList) {
|
|
|
+ StartEntityOperation* startOperat = new StartEntityOperation(pTrigger, entity);
|
|
|
+ Dbg("to start entity: %s ...", entity.entityName);
|
|
|
+ result = startOperat->StartEntity();
|
|
|
+ if (!startOperat->IsDone()) {
|
|
|
+ pendingEntiList.push_back(startOperat);
|
|
|
+ } else {
|
|
|
+ if (ISSUCCEEDED(result)) {
|
|
|
+ Dbg("start entity: %s successfully :)", entity.entityName);
|
|
|
+ } else {
|
|
|
+ Dbg("start entity: %s failed :( EC: %s", entity.entityName, SpStrError(result));
|
|
|
+ }
|
|
|
+ delete startOperat;
|
|
|
+ if (FAILURED(result)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!pendingEntiList.empty()) {
|
|
|
+ result = WaitForAsyncEntitStartOperation(pendingEntiList);
|
|
|
+ }
|
|
|
+ [](std::vector < StartEntityOperation*>& entities) {
|
|
|
+ for (auto& entity : entities) {
|
|
|
+ delete entity;
|
|
|
+ }
|
|
|
+ }(pendingEntiList);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
#endif
|