* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#ifndef AIR_RUNTIME_HETEROGENEOUS_COMMON_SUBPROCESS_SUBPROCESS_MANAGER_H_
#define AIR_RUNTIME_HETEROGENEOUS_COMMON_SUBPROCESS_SUBPROCESS_MANAGER_H_
#include <string>
#include <map>
#include <thread>
#include <mutex>
#include <functional>
#include "ge/ge_api_error_codes.h"
#include "common/plugin/ge_make_unique_util.h"
#include "common/thread_pool/thread_pool.h"
namespace ge {
constexpr uint32_t kAbnormalTypeNode = 1U;
constexpr uint32_t kAbnormalTypeDevice = 2U;
constexpr uint32_t kAbnormalTypeModelInstance = 3U;
enum class ProcStatus : int32_t {
NORMAL = 0,
EXITED,
STOPPED,
INVALID
};
class SubprocessManager {
public:
struct SubprocessConfig {
std::string process_type;
int32_t death_signal = 0;
std::map<std::string, std::string> envs;
std::vector<std::string> args;
std::map<std::string, std::string> kv_args;
std::vector<std::string> unset_envs;
};
GE_DELETE_ASSIGN_AND_COPY(SubprocessManager);
static SubprocessManager& GetInstance();
Status Initialize();
Status ForkSubprocess(const SubprocessConfig &subprocess_config, pid_t &pid);
void NotifySubprocessShutdown(const pid_t &pid);
Status ShutdownSubprocess(const pid_t &pid, const uint32_t wait_time_in_sec = 3U);
void RegExcptHandleCallback(pid_t pid, std::function<void(const ProcStatus &)> callback);
void UnRegExcptHandleCallback(pid_t pid);
void Finalize();
static Status HasFlowGw(bool &has_flowgw);
static std::vector<std::string> FormatArgs(const SubprocessConfig &subprocess_config);
private:
SubprocessManager();
~SubprocessManager() {
Finalize();
}
static Status Execute(const std::string &path, const SubprocessConfig &subprocess_config, char_t *const argv[]);
static Status ToCmdlineArgs(const std::vector<std::string> &args_strings, char_t *var_args[]);
static void FormatKvArgs(const std::map<std::string, std::string> &kv_args,
std::vector<std::string> &out_args);
static Status GetBinDir(std::string &bin_dir);
static Status GetFlowGwBinDir(const std::string &bin_dir, std::string &flowgw_bin_dir);
static bool FileExist(const std::string &file_path);
void MonitorSubprocess();
std::map<std::string, std::string> executable_paths_;
std::atomic<bool> run_flag_;
std::thread watch_sub_proc_thread_;
std::map<pid_t, std::function<void(const ProcStatus &)>> excpt_handle_callbacks_;
std::mutex callbacks_mu_;
ThreadPool pool_{"ge_dpl_subp", 1, false};
std::map<pid_t, bool> planned_shutdown_;
std::map<std::string, ProcStatus> process_status_;
};
}
#endif