diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 404ab6e..0b84592 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -57,6 +57,13 @@ extern "C" { #ifdef __cplusplus } #endif +///////////////////////////////lnk20250118台账变更使用的内存池:动态内存池的方式,每个内存池放一个ied的所有相关内容,这个方案暂不使用,只保留相关实现函数 +// 用于存储终端 ID 和对应的子池 +std::list > pool_list; +/////////////////////////////////////////////////// + + + //ZW 2023-10-10 单条补招结构 class RecallInfo { @@ -191,6 +198,9 @@ std::string LEDGER_UPDATE_FN = "LedgerUpdate.log"; const int MAX_CPUNO = 10; +//lnk20250121终端台账数量配置 +int IED_COUNT = 200; //默认200 + //WW 2-23-08-20 add start otl_connect db; //OTL数据库连接对象 WW 2023-08-20 int g_iOTLFlag = 0; //Sql是否执行标志(0-不执行;1-执行) //lnk202410-22替换web接口后关闭 @@ -666,6 +676,7 @@ void init_config() { std::cout << "Read MONITOR_STATUS:" << MONITOR_STATUS << std::endl; ICD_FLAG = settings.value("Ledger/IcdFlag", 0).toString().toStdString(); std::cout << "Read ICD_FLAG:" << ICD_FLAG << std::endl; + IED_COUNT = settings.value("Ledger/IedCount", 0).toInt(); //////////////////////////////////////////////////添加socket开关/////////////////// SOCKETENABLE = settings.value("Socket/SocketEnable", 0).toInt(); @@ -3849,7 +3860,8 @@ int parse_rpt_log_ini() QStringList* log_temp = new QStringList(); rpt_cfg_strlists.insert(type, rpt_temp); log_cfg_strlists.insert(type, log_temp); - parse_one_rpt_log_ini(ied_usr->dev_flag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type); + //g_DevFlag没有使用 + parse_one_rpt_log_ini(g_DevFlag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type); } /*if (not_loaded[ied_usr->dev_flag]) { @@ -12145,10 +12157,12 @@ int parse_device_cfg_web() std::cout << "terminal_ledger_num:" << count_cfg << std::endl; - g_node->n_clients = count_cfg; //根据台账总数申请空间 - g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); + g_node->n_clients = count_cfg; + //这里开辟的ied的空间由配置文件中的终端台账数量决定lnk20250121 + g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, IED_COUNT * sizeof(ied_t*));//g_node->clients 这块大内存空间存储了 count_cfg 个 ied_t* 类型的指针(即一个指针数组)这是(指向内存块的指针)的指针数组 + //把ied放入数组 for (int k = 0; k < count_cfg; k++) - g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); + g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t));//每个 g_node->clients[k] 指向的内存块是独立的(每个 ied_t 结构体占用的内存块)这是指向内存块的指针 //读取终端台账表替换为web接口 ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -12192,21 +12206,24 @@ int parse_device_cfg_web() //处理终端台账 ied = g_node->clients[count_real++]; - ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); + //这里申请的空间基于ied的数量,挂载到ied上 + ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t));//终端台账在initpool中申请空间 ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; - ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); + //这里申请的空间基于ied的数量,挂载到ied上 + ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t));//监测点台账在initpool中申请空间 if (ied_usr->LD_info == NULL) return APR_ENOMEM; - ied_usr->dev_flag = g_DevFlag; + ied_usr->dev_flag = ENABLE;//终端有效 ied->chncount = 1; - ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); + //这里申请的空间基于ied的数量,挂载到ied上 + ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount);//通信结构在g_cfg_pool中申请空间:终端的ip端口等 ied->channel[0].ied = ied; ied->channel[0].status = STATUS_BREAKOFF; ied->cpucount = 0; @@ -12309,7 +12326,8 @@ int parse_device_cfg_web() cout << "ied_usr->time:" << ied_usr->time << endl; } - chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); + //这里申请的空间基于ied的数量,挂载到ied上 + chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t));//拓展定义的通信结构在g_init_pool中申请空间:拓展记录一些开关时间信息 ied->channel[0].connect = chnl_usr; chnl_usr->chnl = &(ied->channel[0]); chnl_usr->chnl_id = 0; @@ -12413,7 +12431,7 @@ int parse_device_cfg_web() strcpy(line_info.name, monitor_name); cout << "name:" << line_info.name << endl; - line_info.read_flag = 1; //监测点有效 + line_info.read_flag = ENABLE; //监测点有效 //ied = find_ied_from_dev_code(line_info.terminal_code); //不需要再找上级终端了,已经在终端里了 @@ -12427,10 +12445,11 @@ int parse_device_cfg_web() ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; //cpuno默认是1 ied_usr->LD_info[cpuno - 1].ied = ied; - apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); - ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); - ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); - ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); + apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno);//将监测点逻辑号转为PQMonitorPQM+逻辑号 + ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str);//将 str 中的格式化字符串复制到内存池 g_init_pool 中。ied_usr->LD_info[cpuno - 1].LD_name 存储了这个字符串的副本,LD_name 现在是 PQMonitorPQM{cpuno} 的形式。 + //这里申请的空间基于ied的数量,挂载到ied上 + ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); //这两行代码分别为 ied_usr->LD_info[cpuno - 1] 的两个成员(ht_fcd 和 ht_full_fcda)创建了空的哈希表。apr_hash_make(g_init_pool) 会在 g_init_pool 内存池中为这两个哈希表分配内存空间 + ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool);//它们的 key 值和 value 在后续的代码中可能会被填充 ied_usr->LD_info[cpuno - 1].rptcount = 0; cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl; @@ -12442,171 +12461,7 @@ int parse_device_cfg_web() } } } -////////////////////////////////////////////////////////////////////////////////////////////////// -#if 0 - ied = g_node->clients[count_real++]; - ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); - ied->usr_ext = ied_usr; - - if (ied_usr == NULL) - return APR_ENOMEM; - - ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; - ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); - - if (ied_usr->LD_info == NULL) - return APR_ENOMEM; - - ied_usr->dev_flag = g_DevFlag; - ied->chncount = 1; - ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); - ied->channel[0].ied = ied; - ied->channel[0].status = STATUS_BREAKOFF; - ied->cpucount = 0; - - if (strlen(terminal_id) != 0) { - apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", terminal_id);//terminal_id - cout << "ied_usr->terminal_id:" << ied_usr->terminal_id << endl; - } - if (terminal_code != NULL) { - apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", terminal_code);//terminal_code - cout << "ied_usr->terminal_code:" << ied_usr->terminal_code << endl; - - } -/*不需要这三个信息 - if (org_name != NULL) { - apr_snprintf(ied_usr->org_name, sizeof(ied_usr->org_name), "%s", org_name);//org_name - cout << "ied_usr->org_name:" << ied_usr->org_name << endl; - - } - if (maint_name != NULL) { - apr_snprintf(ied_usr->maint_name, sizeof(ied_usr->maint_name), "%s", maint_name);//maint_name - cout << "ied_usr->maint_name:" << ied_usr->maint_name << endl; - - } - if (station_name != NULL) { - apr_snprintf(ied_usr->station_name, sizeof(ied_usr->station_name), "%s", station_name);//station_name - cout << "ied_usr->station_name:" << ied_usr->station_name << endl; - } - */ - if (tmnl_factory != NULL) { - apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", tmnl_factory);//tmnl_factory - cout << "ied_usr->tmnl_factory:" << ied_usr->tmnl_factory << endl; - - } - if (tmnl_status != NULL) { - apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", tmnl_status);//tmnl_status - cout << "ied_usr->tmnl_status:" << ied_usr->tmnl_status << endl; - } - if (dev_type != NULL) { - apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", dev_type);//dev_type - cout << "ied_usr->dev_type:" << ied_usr->dev_type << endl; - } - if (dev_series != NULL) { - apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", dev_seri);//DEV_Series - cout << "defalut dev_series:" << ied_usr->dev_series << endl; - } - else - { - apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series - cout << "defalut dev_series:" << ied_usr->dev_series << endl; - } - if (dev_key != NULL) { - apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", dev_key);//DEV_Key - cout << "defalut dev_key:" << ied_usr->dev_key << endl; - } - else - { - apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key - cout << "defalut dev_key:" << ied_usr->dev_key << endl; - } - -//合并了 -/* cout << "code" << ied_usr->terminal_code << endl; - if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { - terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); - apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_key);//DEV_Key - cout << "dev_key:" << ied_usr->dev_key << endl; - apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_identify_code);//DEV_Series - cout << "dev_series:" << ied_usr->dev_series << endl; - } - else - { - apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key - cout << "defalut dev_key:" << ied_usr->dev_key << endl; - apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series - cout << "defalut dev_series:" << ied_usr->dev_series << endl; - }*/ - - ied->channel[0].channel_type = CHANNEL_TYPE_IPV4;//channel - ied->channel[0].addr_str[LONGNAME - 1] = 0;//DEV_IP - if (addr_str != NULL) { - ied->channel[0].addr = ntohl(inet_addr(addr_str));//DEV_IP - strncpy(ied->channel[0].addr_str, addr_str, LONGNAME - 1);//DEV_IP - cout << "ied_usr->addr_str:" << ied->channel[0].addr_str << endl; - } - else - { - ied->channel[0].addr = ntohl(inet_addr("0.0.0.0"));//DEV_IP - strncpy(ied->channel[0].addr_str, addr_str, LONGNAME - 1);//DEV_IP - cout << "ied_usr->addr_str:" << ied->channel[0].addr_str << endl; - } - if (port_char != NULL) { - int port = 102; - if (stringToInt(port_char, &port)) { - // 转换成功,portStr全为数字,并且已经转换为int类型的port - ied->channel[0].port = port;//DEV_PortID - cout << "ied_usr->port:" << ied->channel[0].port << endl;//DEV_PortID - } - else { - ied->channel[0].port = 102;//DEV_PortID - cout << "ied_usr->port:" << port_char << ",非合法端口.使用默认端口:" << ied->channel[0].port << endl;//DEV_PortID - } - } - if (timestamp.year != 0) { - //// 构造struct tm对象 - struct tm timeinfo; - timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 - timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 - timeinfo.tm_mday = timestamp.day; - timeinfo.tm_hour = timestamp.hour; - timeinfo.tm_min = timestamp.minute; - timeinfo.tm_sec = timestamp.second; - time_t time = std::mktime(&timeinfo); - ied_usr->time = static_cast(time); - cout << "ied_usr->time:" << ied_usr->time << endl; - } - - chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); - ied->channel[0].connect = chnl_usr; - chnl_usr->chnl = &(ied->channel[0]); - chnl_usr->chnl_id = 0; - chnl_usr->m_state = CHANNEL_DISCONNECTED; - chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1); - g_pt61850app->chnl_counts++; - - //调试用 - std::cout << "value:" << terminal_id <<" "<n_clients = count_real; @@ -13096,7 +12951,7 @@ void OnTimerThread::run() pthread_mutex_lock(&mtx);//lnk20250114 std::string mp_num_str = ""; mp_num_str.append("connected device count:"); - mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString()); + mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString());//记录连接的检测点数 mp_num_str.append(",g_node clients:"); mp_num_str.append(QString::number(g_node->n_clients).toStdString()); @@ -14142,7 +13997,7 @@ void SOEFileWeb_test() /*封装C可调用的台账更新函数 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //3-写入台账内容////////////////////////////// -int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index) +int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index,int ied_take) { chnl_usr_t* chnl_usr = NULL; ied_usr_t* ied_usr = NULL; @@ -14183,8 +14038,10 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ""); // 默认为空字符串 printf("ied_usr->dev_key (default): %s\n", ied_usr->dev_key); } - ied_usr->dev_idx = terminal_index; // 最新的一个终端排号 + + ied_usr->dev_idx = terminal_index; //终端排号 printf("dev_idx: %d\n", ied_usr->dev_idx); + ied->channel[0].channel_type = CHANNEL_TYPE_IPV4; // channel ied->channel[0].addr_str[LONGNAME - 1] = 0; // DEV_IP if (update[i].addr_str != NULL) { @@ -14207,6 +14064,7 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i printf("ied_usr->port: %s, 非合法端口. 使用默认端口: %d\n", update[i].port, ied->channel[0].port); // DEV_PortID } } + if (update[i].timestamp != NULL && strlen(update[i].timestamp) > 0) { // 构造struct tm对象 struct tm timeinfo = {0}; // 初始化为0 @@ -14235,13 +14093,22 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i return -1; } } - chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); - ied->channel[0].connect = chnl_usr; + + //如果是使用已有空间则不需要再申请 + if(!ied_take){ + chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); + ied->channel[0].connect = chnl_usr; + g_pt61850app->chnl_counts++; //新增的需要添加 + } + else{ + chnl_usr = (chnl_usr_t*)ied->channel[0].connect; + } + chnl_usr->chnl = &(ied->channel[0]); chnl_usr->chnl_id = 0; chnl_usr->m_state = CHANNEL_DISCONNECTED; chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1); - g_pt61850app->chnl_counts++; + // 将 monitorData 中的数据写入到 LD_info 中 int count_real_monitor = 0; //遍历监测点台账的计数器 int j; @@ -14249,9 +14116,10 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i monitor monitor_data = update[i].line[j]; //监测点计数 count_real_monitor++; - // 初始化 LD_info + // 初始化用于值拷贝的 LD_info,里面涉及指针的部分都为空 LD_info_t line_info; memset(&line_info, 0, sizeof(line_info)); + char logical_device_seq[64]; // 填充监测点信息 strncpy(line_info.mp_id, monitor_data.monitor_id, sizeof(line_info.mp_id) - 1); @@ -14269,6 +14137,7 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i printf("logical_device_seq: %d\n", line_info.cpuno); } line_info.line_id = count_real_monitor; // 记录终端排号 + printf("line_id: %d\n", line_info.line_id); printf("mp_id: %s\n", line_info.mp_id); printf("terminal_code: %s\n", line_info.terminal_code); @@ -14276,6 +14145,7 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i printf("v_wiring_type: %s\n", line_info.v_wiring_type); printf("monitor_status: %s\n", line_info.monitor_status); printf("name: %s\n", line_info.name); + // 填充时间戳 if (update[i].timestamp[0] != '\0') { struct tm timeinfo; @@ -14313,13 +14183,24 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i ied_usr->LD_info[cpuno - 1] = line_info; // cpuno默认是1 ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); - ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); - ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); - ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); + // 仅在没有值时更新 LD_name,避免重复分配内存 + if (ied_usr->LD_info[cpuno - 1].LD_name == NULL) { + ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); + } else {//已有则替换,在原有空间上覆盖 + apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, sizeof(ied_usr->LD_info[cpuno - 1].LD_name)); + } + + // 更新哈希表,避免重复分配内存,原来的ied就分配了空的哈希表就不再分配,这个哈希表暂时没有作用 + if (ied_usr->LD_info[cpuno - 1].ht_fcd == NULL) { + ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); + } + if (ied_usr->LD_info[cpuno - 1].ht_full_fcda == NULL) { + ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); + } ied_usr->LD_info[cpuno - 1].rptcount = 0; printf("rptcount: %d\n", ied_usr->LD_info[cpuno - 1].rptcount); if (cpuno > ied->cpucount) { - ied->cpucount = cpuno; + ied->cpucount = cpuno;//如果原有的监测点比新增的监测点多,没有被覆盖的部分仍存在内存中,但是这个值会保证我们不会访问到那些之前的没有被覆盖的监测点 } } // ied_usr->LD_info[j] = line_info; @@ -14411,33 +14292,47 @@ void create_ledger_log(trigger_update_xml_t* ledger_update_xml) { log_file.close(); std::cout << "Ledger log has been updated." << std::endl; } -/////////////////////////////////////////////////////////////////////////// -// 清空 ied_usr_t 结构体内容的函数 -void clear_ied_usr(ied_t* ied) { - if (ied && ied->usr_ext) { // 检查 usr_ext 是否为 NULL - ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext; - - // 清空字符串成员 - memset(ied_usr->dev_type, 0, sizeof(ied_usr->dev_type)); - memset(ied_usr->dev_key, 0, sizeof(ied_usr->dev_key)); - memset(ied_usr->dev_series, 0, sizeof(ied_usr->dev_series)); - memset(ied_usr->terminal_id, 0, sizeof(ied_usr->terminal_id)); - memset(ied_usr->org_name, 0, sizeof(ied_usr->org_name)); - memset(ied_usr->maint_name, 0, sizeof(ied_usr->maint_name)); - memset(ied_usr->station_name, 0, sizeof(ied_usr->station_name)); - memset(ied_usr->tmnl_factory, 0, sizeof(ied_usr->tmnl_factory)); - memset(ied_usr->tmnl_status, 0, sizeof(ied_usr->tmnl_status)); - memset(ied_usr->terminal_code, 0, sizeof(ied_usr->terminal_code)); - - // 清空数值类型的成员 - ied_usr->dev_idx = 0; - ied_usr->dev_flag = 0; - ied_usr->cookie = NULL; - ied_usr->last_call_wavelist_time = 0; - ied_usr->time = 0; - ied_usr->update_flag = 0; +///////////////////////////////////////////////////////////////////////////台账内存分配部分功能代码:未使用 +// 删除指定的子池 +void delete_sub_pool(const char* terminal_id) { + std::list >::iterator it; + + for (it = pool_list.begin(); it != pool_list.end(); ++it) { + if (it->first == terminal_id) { + apr_pool_destroy(it->second); // 销毁子池 + pool_list.erase(it); // 从容器中移除 + break; + } } } +//找对应的子池 +apr_pool_t* find_sub_pool(const char* terminal_id) { + std::list >::iterator it; + + for (it = pool_list.begin(); it != pool_list.end(); ++it) { + if (it->first == terminal_id) { + return it->second; // 找到对应的子池 + } + } + + return NULL; // 没有找到对应的子池 +} +// 创建子池并添加到容器 +apr_pool_t* create_sub_pool(apr_pool_t* parent_pool, const char* terminal_id) { + apr_pool_t* new_sub_pool = NULL; + + // 在父池中创建一个子池 + apr_pool_create(&new_sub_pool, parent_pool); + + if (new_sub_pool == NULL) { + return NULL; // 创建失败 + } + + // 将子池和终端 ID 存储在容器中 + pool_list.push_back(std::make_pair(std::string(terminal_id), new_sub_pool)); + + return new_sub_pool; +} /*封装C可调用的台账更新函数 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/mms/mms_process.c b/mms/mms_process.c index 3ee14b5..57e5432 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -33,7 +33,9 @@ extern pthread_mutex_t mtx; extern apr_pool_t* g_cfg_pool; extern apr_pool_t* g_init_pool; -extern int g_DevFlag; +extern int g_DevFlag; //日志配置中读取的参数,暂无特定使用lnk20250121 + +extern int IED_COUNT; //lnk20250115end @@ -832,50 +834,84 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) } } - if (!new_in_work_found) { //这是全新的台账,不是正在工作的台账 + if (!new_in_work_found) { //这是全新的台账,在台账数组中没有包含这个设备 + int terminal_index; + int ied_take = 0; //当前台账数组里有不使用的ied空间?0没有,1有 //进行台账添加和初始化操作 //1-申请新的内存空间////////////////////////////// //新的台账数量 (n_clients) 和原有的台账数量 (原数量为 g_node->n_clients) int new_client_count = g_node->n_clients + 1; // 增加一个新的台账 - // 申请新的内存空间:原来的 clients 指向一个指针数组,我们为新的数量分配更多内存 - ied_t** new_clients = (ied_t**)apr_pcalloc(g_cfg_pool, new_client_count * sizeof(ied_t*)); + //判断新增进程后是否超过原有的台账数组,如果超过了就从不使能的ied空间中找可用空间,如果还是没有那就提示不能荷载更多终端 + if(new_client_count > IED_COUNT){ + ied_t *ied_unused = NULL; + ied_usr_t* ied_usr_unused = NULL; + ied_unused = find_ied_from_terminal_id(); + if(ied_unused != NULL){ + ied_usr_unused = (ied_usr_t*)ied_unused->usr_ext; + ied = ied_unused; //新增的ied指向已有的未使用的ied空间 + terminal_index = ied_usr_unused->dev_idx //记录这个ied的编号 - // 复制原来的数据到新分配的内存空间 - int k; - for (k = 0; k < g_node->n_clients; k++) { - new_clients[k] = g_node->clients[k]; - } + //打印提示 + printf("!!!!!!!!ied index:%d ,terminal_id:%s has been taken!!!!!!!!!!\n",ied_usr_unused->dev_idx,ied_usr_unused->terminal_id); - // 为新增的台账申请内存空间 - new_clients[g_node->n_clients] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); + //终端初始化,不需要再申请空间 + ied_usr = (ied_usr_t*)ied->usr_ext; + ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; - // 更新指针和台账数量 - g_node->clients = new_clients; // 将 clients 指向新的内存空间 - g_node->n_clients = new_client_count; // 更新台账数量 - //1-申请新的内存空间////////////////////////////// + ied_usr->dev_flag = ENABLE;//终端有效 - //2-处理终端台账/////////////////////////////////// - ied = g_node->clients[new_client_count - 1];//终端台账指针定向到新分配的内存的最后一位 - ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); - ied->usr_ext = ied_usr; - if (ied_usr == NULL) - return APR_ENOMEM; - ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; - ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); - if (ied_usr->LD_info == NULL) - return APR_ENOMEM; - ied_usr->dev_flag = g_DevFlag; - ied->chncount = 1; - ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); - ied->channel[0].ied = ied; - ied->channel[0].status = STATUS_BREAKOFF; - ied->cpucount = 0; - //2-处理终端台账/////////////////////////////////// + ied->chncount = 1; //通信端口数 + ied->channel[0].ied = ied; //通道的所属设备 + ied->channel[0].status = STATUS_BREAKOFF;//初始化为通信中断 + ied->cpucount = 0; //监测点数初始为0,读取监测点台账时写入 + + ied_take = 1;//ied之前存在 + + } + else{ + printf("!!!!!!!!!!ledger array is full!!!!!!\n"); + return; + } + + } + else{//新增台帐后仍在台账范围 + // 新增的台账在已有的台账数组中记录 + g_node->clients[new_client_count - 1] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); + + // 更新台账数量 + g_node->n_clients = new_client_count; // 更新台账数量 + //1-申请新的内存空间////////////////////////////// + + //2-处理终端台账/////////////////////////////////// + ied = g_node->clients[new_client_count - 1];//终端台账指针定向到ied数组当前位置的后一位 + + terminal_index = new_client_count - 1;//新的台账终端 + + ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); + ied->usr_ext = ied_usr;//内存挂到ied上 + if (ied_usr == NULL) + return APR_ENOMEM; + + ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000;//从FeProject/子功能目录/etc/pt61850netd_pqfe.xml中读取的总查询时间 + + ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t));//内存挂到ied上 + if (ied_usr->LD_info == NULL) + return APR_ENOMEM; + + ied_usr->dev_flag = ENABLE;//终端有效 + + ied->chncount = 1; //通信端口数 + ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount);//内存挂到ied上 + ied->channel[0].ied = ied; //通道的所属设备 + ied->channel[0].status = STATUS_BREAKOFF;//初始化为通信中断 + ied->cpucount = 0; //监测点数初始为0,读取监测点台账时写入 + //2-处理终端台账/////////////////////////////////// + } //3-写入台账内容////////////////////////////// - int ret = update_one_terminal_ledger(update,i,ied,g_node->n_clients); + int ret = update_one_terminal_ledger(update,i,ied,terminal_index,ied_take); if(ret){ printf("ledger can not be update!!!!!quit process!!!!!\n"); return 0; @@ -918,7 +954,7 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) //////////////////////////////////////////////////////////////////////////////modify update = ledger_update_xml->modify_updates; //处理新增台账部分 - update_num = ledger_update_xml->modify_updates_num; + update_num = ledger_update_xml->modify_update_num; printf("modify ledger num:%d\n",update_num); for (i=0; idelete_updates; //处理新增台账部分 - update_num = ledger_update_xml->delete_updates_num; + update_num = ledger_update_xml->delete_update_num; printf("delete ledger num:%d\n",update_num); for (i=0; iusr_ext; + ied_usr_t* ied_usr_find = NULL; //遍历的ied + ied_usr = (ied_usr_t*)ied->usr_ext;//要删除的ied for (iedno = 0; iedno < g_node->n_clients; iedno++) { ied_find = g_node->clients[iedno]; ied_usr_find = (ied_usr_t*)ied_find->usr_ext; if (ied_usr_find && strcmp(ied_usr_find->terminal_id, ied_usr->terminal_id) == 0) { - index_to_remove = iedno; + index_to_remove = iedno;//找到要删除的ied在g_node中的位置 break; //找到退出 } } - - clear_ied_usr(ied); //台账数据部分清空 + - // 先清理要删除的 ied 的内存 - ied_t* ied_to_remove = g_node->clients[index_to_remove]; - memset(ied_to_remove, 0, sizeof(ied_t)); + // 先清理要删除的 ied 的内容 + ied_t* ied_to_remove = g_node->clients[index_to_remove];//指向g_node对应的内存区 - // 释放 ied_usr 结构体的内存(如果有) + if(ied_to_remove == ied){//通过终端id找到的ied应该也指向g_node对应的内存区 + printf("this ied is ied_to_remove\n"); + } + + //释放ied通信的内存 + if (ied_to_remove->channel) { + apr_pool_clear(ied_to_remove->channel); // 释放 g_cfg_pool 内存池中的 channel 内存 + ied_to_remove->channel = NULL; + } + + // 释放 ied监测点台账结构体的内存 + if (ied_to_remove->usr_ext->LD_info) { + apr_pool_clear(ied_to_remove->usr_ext->LD_info); // 释放 g_init_pool 内存池中的 LD_info 内存 + ed_to_remove->usr_ext->LD_info = NULL; + } + + // 释放 ied台账结构体的内存 if (ied_to_remove->usr_ext) { - apr_pool_clear(g_init_pool); // 如果你使用的是同一个内存池,清理它 + apr_pool_clear(ied_to_remove->usr_ext); // 释放 g_init_pool 内存池中的 ied_usr 内存 + ied_to_remove->usr_ext = NULL; } // 移动指针数组中的元素 - for (int i = index_to_remove; i < g_node->n_clients - 1; i++) { + for (i = index_to_remove; i < g_node->n_clients - 1; i++) { g_node->clients[i] = g_node->clients[i + 1]; } @@ -1046,6 +1097,9 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) ied_t** new_clients = (ied_t**)apr_pcalloc(g_cfg_pool, (g_node->n_clients - 1) * sizeof(ied_t*)); memcpy(new_clients, g_node->clients, (g_node->n_clients - 1) * sizeof(ied_t*)); + //释放原来的内存块 + apr_pool_clear(g_node->clients); + // 更新指针数组和台账数量 g_node->clients = new_clients; g_node->n_clients--; @@ -1569,7 +1623,7 @@ void CheckNextNotConnectedChannel() ST_CHAR serverARName[32]; ied_usr_t *ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext; apr_snprintf(serverARName,sizeof(serverARName),"%s:%d",chnl_usr->ip_str,chnl_usr->chnl->port); - if (chnl_usr->chnl->ied->cpucount != NULL && chnl_usr->chnl->ied->cpucount > 0) {//2023-09-26 czy 如果line count<0 不需要连接 + if (chnl_usr->chnl->ied->cpucount != NULL && chnl_usr->chnl->ied->cpucount > 0 && ied_usr->dev_flag == ENABLE) {//2023-09-26 czy 如果line count<0 不需要连接//lnk20250121如果终端无效则不连接 ret = mms_connectToServer(ied_usr->dev_key, ied_usr->dev_series, serverARName, &(chnl_usr->net_info), &(chnl_usr->m_reqCtrl)); if (ret == SD_SUCCESS) { diff --git a/mms/rdb_client.h b/mms/rdb_client.h index 78ef36a..5499e85 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -68,6 +68,10 @@ CHECK_NOTHING CHECK_SYN #define DEFAULT_EDIT_FXDAREANO (0x80FE) /**< 默认编辑区定值区号 */ #define FIXED_AREA_GRP_DOT2_EDIT_AREA (2) /**< 定值区组->编辑定值区点 */ +//lnk添加使能标志20250121 +#define ENABLE 1 +#define UNUSED 0 + extern unsigned int g_node_id; typedef struct element_usr_t element_usr_t; @@ -463,15 +467,15 @@ LD_info_t* find_LD_info_only_from_mp_id(char* mp_id); ////////////////////////////////lnk20250115 int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml); extern const int MAX_CPUNO; -extern int stringToInt(const char* str, int* result); -extern bool isCharPtrEmpty(const char* str); -extern int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml); -extern int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index); -extern void print_trigger_update_xml(const trigger_update_xml_t* trigger_update); -extern char* parse_model_cfg_web_one(ied_t* ied); -extern void Set_xml_nodeinfo_one(char* dev_type); -extern void create_ledger_log(trigger_update_xml_t* ledger_update_xml); -extern void clear_ied_usr(ied_t* ied); +int stringToInt(const char* str, int* result); +bool isCharPtrEmpty(const char* str); +int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml); +int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index,int ied_take); +void print_trigger_update_xml(const trigger_update_xml_t* trigger_update); +char* parse_model_cfg_web_one(ied_t* ied); +void Set_xml_nodeinfo_one(char* dev_type); +void create_ledger_log(trigger_update_xml_t* ledger_update_xml); +ied_t* find_ied_from_terminal_id(); //////////////////////////////// int parse_3s_xml(trigger_3s_xml_t* trigger_3s_xml); int create_3s_xml(trigger_3s_xml_t* trigger_3s_xml); diff --git a/mms/rdb_ext_utils.c b/mms/rdb_ext_utils.c index cdad907..60cf2dd 100644 --- a/mms/rdb_ext_utils.c +++ b/mms/rdb_ext_utils.c @@ -308,6 +308,21 @@ ied_t* find_ied_from_terminal_id(char terminal_id[]) } return NULL; } +//lnk20250121找不使用的ied空间 +ied_t* find_ied_from_terminal_id() +{ + ied_t* ied_find_unused = NULL; + int iedno; + ied_usr_t* ied_usr_find_unused = NULL; + for (iedno = 0; iedno < g_node->n_clients; iedno++) { + ied_find_unused = g_node->clients[iedno]; + ied_usr_find_unused = (ied_usr_t*)ied_find_unused->usr_ext; + if (ied_usr_find_unused && ied_usr_find_unused->dev_flag == UNUSED) { + return ied_find_unused; + } + } + return NULL; +} LD_info_t* find_LD_info_from_line_id(ied_t* ied, int line_id) {