diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 486e775..989fc22 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -2183,11 +2183,76 @@ int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int //WW2023-11-01 end //补招部分//////////////////////////////////////////////////////////////////////////////// + +////////////////////////////20250801 +/* 最小块,每次至少扩容这么多;也可以调大一点 */ +#define RECALL_CHUNK 64 + +/* 初始化 */ +void recall_xml_init(recall_xml_t *rx) // ★ +{ + rx->work_cnt = rx->work_cap = 0; + rx->new_cnt = rx->new_cap = 0; + rx->work_recalls = rx->new_recalls = nullptr; +} + +/* 若需要,扩容 `*arr` 直到能放下 needed 条记录 */ +static int ensure_cap(recall_t **arr, int *cap, int need) +{ + if (need <= *cap) return 0; + + int new_cap = (*cap) ? (*cap) : 16; + while (new_cap < need) new_cap <<= 1; + + /* C++ 里要显式转换 */ + void *mem = realloc(*arr, new_cap * sizeof(recall_t)); + if (!mem) return -1; + + *arr = static_cast(mem); // ★ 显式 static_cast + *cap = new_cap; + return 0; +} + +/* push 到 work / new 数组 */ +static int push_work(recall_xml_t *rx, const recall_t *rec) +{ + if (ensure_cap(&rx->work_recalls, &rx->work_cap, rx->work_cnt + 1)) + return -1; + rx->work_recalls[rx->work_cnt++] = *rec; + return 0; +} +static int push_new(recall_xml_t *rx, const recall_t *rec) +{ + if (ensure_cap(&rx->new_recalls, &rx->new_cap, rx->new_cnt + 1)) + return -1; + rx->new_recalls[rx->new_cnt++] = *rec; + return 0; +} + +/* 释放内存(栈退出前或不用时调用) */ +void recall_xml_free(recall_xml_t *rx) // ★ +{ + for (int i = 0; i < rx->work_cnt; ++i) + free(rx->work_recalls[i].line_id); + for (int i = 0; i < rx->new_cnt; ++i) + free(rx->new_recalls[i].line_id); + + free(rx->work_recalls); + free(rx->new_recalls); + + recall_xml_init(rx); /* 复位为全 0,防止悬挂指针 */ +} +////////////////////////////20250801 + void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& recall_e, char* id) { - recall_t recall; + //recall_t recall;//lnk20250801 - recall.line_id = id; + //recall.line_id = id; + + recall_t recall = {0}; + + recall.line_id = strdup(id); /* malloc 字符串 */ QDateTime start_dt = QDateTime::fromString(recall_e.attribute("StartTime"), "yyyy-MM-dd hh:mm:ss"); recall.start_time = start_dt.toMSecsSinceEpoch() / 1000; @@ -2201,10 +2266,12 @@ void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& reca << " " << recall.start_time << " " << recall.end_time; if (parentTag == "Work") { - recall_xml->work_recalls[recall_xml->work_recall_num++] = recall; + //recall_xml->work_recalls[recall_xml->work_recall_num++] = recall; + push_work(recall_xml, &recall); } else if (parentTag == "New") { - recall_xml->new_recalls[recall_xml->new_recall_num++] = recall; + //recall_xml->new_recalls[recall_xml->new_recall_num++] = recall; + push_new(recall_xml, &recall); } } @@ -2295,7 +2362,7 @@ int parse_recall_xml(recall_xml_t* recall_xml, char* id) return APR_SUCCESS; } -void process_recall_config(recall_xml_t* recall_xml) +/*void process_recall_config(recall_xml_t* recall_xml) { int i, j; recall_t* recall; @@ -2328,13 +2395,18 @@ void process_recall_config(recall_xml_t* recall_xml) if (LD_info->autorecallflag != 0 || LD_info->autorecallcount == 0) { // if (LD_info->autorecallcount != 0) { for (int j = 0; j < LD_info->autorecallcount; j++) { - delete LD_info->autorecall[j]; + delete[] LD_info->autorecall[j];//避免重复释放lnk20250801 } delete LD_info->autorecall; LD_info->autorecallcount = 0; } LD_info->autorecallcount = recall_num; LD_info->autorecall = new autorecall_t * [recall_num]; + + for (int k = 0; k < recall_num; ++k) { + LD_info->autorecall[k] = nullptr; //避免野指针lnk20250801 + } + for (int j = 0; j < recall_num; j++) { printf("\n %d ===== %d\n", recall[j].start_time, recall[j].end_time); LD_info->autorecall[j] = new autorecall_t[1]; @@ -2352,10 +2424,104 @@ void process_recall_config(recall_xml_t* recall_xml) } } + + //调试 + printf("== autorecall count = %d ==\n", LD_info->autorecallcount); + for (int j = 0; j < LD_info->autorecallcount; ++j) { + if (LD_info->autorecall[j] == nullptr) { + printf("autorecall[%d] = nullptr !!!\n", j); + } else { + printf("autorecall[%d] = %p | start = %d, end = %d\n", + j, LD_info->autorecall[j], + LD_info->autorecall[j]->start, LD_info->autorecall[j]->end); + } + } + + } -} + +}*/ +void process_recall_config(recall_xml_t *rx) +{ + if (rx->new_cnt) { + /* 预留空间 */ + if (ensure_cap(&rx->work_recalls, &rx->work_cap, + rx->work_cnt + rx->new_cnt)) + return; /* 内存不足,直接返回 */ + + memcpy(&rx->work_recalls[rx->work_cnt], + rx->new_recalls, + rx->new_cnt * sizeof(recall_t)); + rx->work_cnt += rx->new_cnt; + rx->new_cnt = 0; + } + + /* work 列表为空,直接结束 */ + if (rx->work_cnt == 0) + return; + + + recall_t *recall = rx->work_recalls; + int recall_num = rx->work_cnt; + + LD_info_t *LD_info = find_LD_info_only_from_mp_id(recall[0].line_id); + printf("\n recall[0].line_id == %s \n", recall[0].line_id); + printf("\n recall[0].start_time == %lld \n", recall[0].start_time); + + if (!LD_info || LD_info->read_flag == 0) { + printf("\n Find LD_info == null \n"); + return; + } + + printf("\n Find LD_info != null \n"); + + /* 若正在补招中则跳过;否则装载新补招队列 */ + if (LD_info->autorecallflag != 0 || LD_info->autorecallcount == 0) { + + /* 先释放旧队列 */ + if (LD_info->autorecallcount != 0) { + for (int j = 0; j < LD_info->autorecallcount; ++j) + delete[] LD_info->autorecall[j]; /* 原逻辑 */ + delete LD_info->autorecall; + LD_info->autorecallcount = 0; + } + + /* 重新分配新队列,大小 = recall_num */ + LD_info->autorecallcount = recall_num; + LD_info->autorecall = new autorecall_t*[recall_num]; + + for (int k = 0; k < recall_num; ++k) + LD_info->autorecall[k] = nullptr; + + for (int j = 0; j < recall_num; ++j) { + LD_info->autorecall[j] = new autorecall_t[1]; + LD_info->autorecall[j]->start = recall[j].start_time; + LD_info->autorecall[j]->end = recall[j].end_time; + LD_info->autorecall[j]->need_steady = recall[j].need_steady; + LD_info->autorecall[j]->need_voltage = recall[j].need_voltage; + + printf("\n %lld ===== %lld\n", + recall[j].start_time, recall[j].end_time); + } + LD_info->autorecallflag = 0; /* 重置“正在补招”标志 */ + } + + /* 调试输出 */ + if(DEBUGOPEN){ + printf("== autorecall count = %d ==\n", LD_info->autorecallcount); + for (int j = 0; j < LD_info->autorecallcount; ++j) { + if (!LD_info->autorecall[j]) + printf("autorecall[%d] = nullptr !!!\n", j); + else + printf("autorecall[%d] = %p | start = %lld, end = %lld\n", + j, LD_info->autorecall[j], + LD_info->autorecall[j]->start, + LD_info->autorecall[j]->end); + } + } +} ////////////////////////////////////////////////////////////////////////////////// void WebSocketThread::run() @@ -5881,7 +6047,7 @@ void clearLDInfo(LD_info_t *ld_info) { for (int i = 0; i < ld_info->autorecallcount; ++i) { if (ld_info->autorecall[i] != nullptr) { memset(ld_info->autorecall[i], 0, sizeof(autorecall_t)); - delete ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放 + delete[] ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放lnk20250801 } } delete ld_info->autorecall; //删除数组空间 diff --git a/json/save2json.cpp b/json/save2json.cpp index b439980..c0784bc 100644 --- a/json/save2json.cpp +++ b/json/save2json.cpp @@ -93,7 +93,6 @@ mqconsumerThread mqconsumerThrd;//mq消费者线程lnk20241213 OnTimerThread onTimerThrd;//定时线程 -extern int g_iSqlListSize; //Sql执行语句链表允许最大元素个数 注:Sql链表中元素超过此个数,多出元素需移除! extern int FILE_FLAG; extern int SEND_FLAG; extern char* BROKER_LIST; diff --git a/mms/mms_process.c b/mms/mms_process.c index b91b6d1..e9b8a23 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -696,7 +696,7 @@ void process_3s_config(trigger_3s_xml_t *trigger_3s_xml) create_3s_xml(trigger_3s_xml); //写入文件的work块 } -void del_process_recall_config(recall_xml_t* recall_xml) +/*void del_process_recall_config(recall_xml_t* recall_xml) { int i,j; recall_t *recall; @@ -733,7 +733,7 @@ void del_process_recall_config(recall_xml_t* recall_xml) } -} +}*/ void check_3s_config() { @@ -1402,9 +1402,14 @@ void Check_Recall_Config(char *id) //检查补招配置文件Recall.xml if (g_node_id == HIS_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID || g_node_id == RECALL_HIS_DATA_BASE_NODE_ID || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) { recall_xml_t recall_xml; - memset((char*)&recall_xml, 0, sizeof(recall_xml_t)); + //memset((char*)&recall_xml, 0, sizeof(recall_xml_t)); + + recall_xml_init(&recall_xml); + parse_recall_xml(&recall_xml,id); //解析补招文件,目录下所有属于这个监测点的文件都读取 process_recall_config(&recall_xml); //解析的补招数据赋值到全局变量 + + recall_xml_free(&recall_xml); } } diff --git a/mms/mmscli_log.c b/mms/mmscli_log.c index 1d530ff..527469b 100644 --- a/mms/mmscli_log.c +++ b/mms/mmscli_log.c @@ -56,6 +56,8 @@ SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; extern pt61850app_t* g_pt61850app; +extern bool DEBUGOPEN; + /************************************************************************/ /* Static function prototypes. */ /************************************************************************/ @@ -126,7 +128,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, double start, end; static double last_check_recall_config_time = 0.0; - printf("\nbrf for"); + if(DEBUGOPEN)printf("\nbrf for"); for (j = 0; j < jou_entry->ef.data.num_of_var; j++) { printf("\nfor %d", jou_entry->ef.data.num_of_var); @@ -146,7 +148,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, do_name++; } - printf("\nbrf if"); + if(DEBUGOPEN)printf("\nbrf if"); if (sel_mvl_type_ctrl_flag(do_name) == -1) { var_type_id = mms_var_type_id_create(clientNetInfo, DOM_SPEC, @@ -157,15 +159,15 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, add_mvl_type_ctrl(doname, var_type_id); } - printf("\nbrf var_type_id"); + if(DEBUGOPEN)printf("\nbrf var_type_id"); var_type_id = sel_mvl_type_ctrl_flag(do_name); - printf("\nafter var_type_id"); + if(DEBUGOPEN)printf("\nafter var_type_id"); if (var_type_id < 0) { continue; } log_var_jou_data(var_type_id,&(jou_entry->ef.data.list_of_var[j].value_spec),&mms_dec_data, do_name); - printf("\nafter log_var_jou_data"); + if(DEBUGOPEN)printf("\nafter log_var_jou_data"); if (timeflag) { int readtime = 0; int readquailty = 0; diff --git a/mms/rdb_client.h b/mms/rdb_client.h index f4af7e1..bb2c9d3 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -144,13 +144,19 @@ struct recall_t{ int need_voltage; }; typedef struct recall_xml_t recall_xml_t; -struct recall_xml_t{ +/*struct recall_xml_t{ int work_recall_num; int new_recall_num; recall_t work_recalls[MAX_RECALL_NUM]; recall_t new_recalls[MAX_RECALL_NUM]; +};*/ +/* 动态数组 + 容量字段 lnk20250801*/ +struct recall_xml_t{ + int work_cnt, work_cap; + int new_cnt , new_cap; + recall_t *work_recalls; + recall_t *new_recalls; }; - ///////////////////////////////////////////////////////////// struct element_usr_t{ char* FCD_ref; @@ -494,6 +500,9 @@ int delete_recall_xml(char* id); int parse_recall_xml(recall_xml_t* recall_xml,char *id); void process_recall_config(recall_xml_t* recall_xml); +void recall_xml_free(recall_xml_t *rx);//lnk20250801 +void recall_xml_init(recall_xml_t *rx); + int init_rptctrl_by_count(LD_info_t* LD_info,int rptcount); int fill_rptctrl_by_cfg(LD_info_t* LD_info,int rptno,char *buf); int init_logctrl_by_count(LD_info_t* LD_info,int logcount);