/* * 模块名称:挂起 recv 请求表(阻塞 recv 挂起模型) * 文件说明:阻塞 recv 的"挂起请求"数据结构与生命周期:登记 / 每轮完成检查 / * 取消(close、网络重建、对账 resync)/ 幂等清理。 * 架构与五路语义见 docs/网络/Net层阻塞模型架构设计.md * 依赖:net_types.h(net_sock_t);消费方 = net_socket.c(消息分派 / close / * 重建 / 对账) * 限定条件:除 net_pending_active / net_pending_clear(纯 RAM 读)外, * 全部函数须 netTask 上下文 */ #ifndef NET_PENDING_H #define NET_PENDING_H #include #include "FreeRTOS.h" #include "task.h" #include "net_types.h" /* 内部哨兵:pending 已登记(消息分派据此跳过即时通知;取值不与字节数空间冲突) */ #define NET_PENDING_REGISTERED 0x70000000 /* 挂起超时留痕探针:排查"调用方挂死唤不醒"时置 1——挂起超 NET_RECV_TRIPWIRE_MS * 只留一条 [ERR](哪个 fd/多少毫秒/什么基准),绝不强制结束、绝不伪造返回值。 * 开与关语义完全一致,差别只在留痕;默认 0 = 产品构建零成本。 * 见 docs/网络/Net层阻塞模型架构设计.md §9 */ #define NET_PENDING_TRIPWIRE 0 #if NET_PENDING_TRIPWIRE #define NET_RECV_TRIPWIRE_MS 60000U /* 挂起超时留痕阈值(ms) */ #endif /* * 函数功能:捕获执行任务句柄(net_init 顶部调用一次;登记守卫据此拒绝自等待死锁) * 入口参数:无 * 出口参数:无 * 返回值:无 * 限定条件:执行任务(netTask / 硬件层 = testTask)上下文,创建消息队列前 */ void net_pending_capture_owner(void); /* * 函数功能:登记一个挂起 recv 请求(net_recv_locked 的阻塞无数据路径) * 入口参数:sockfd - Socket 描述符 (0~7) int * buf - 调用方接收缓冲(须保持有效至完成) void * * len - 缓冲容量 int * to_ms - 本次等待预算(0 = 无限等待) uint32_t * caller - 调用方任务句柄(完成通知目标) TaskHandle_t * 出口参数:无 * 返回值:NET_PENDING_REGISTERED - 登记成功(分派跳过即时通知) * -1 - 拒绝(同 fd 已有挂起 / 执行任务自身发起;错误码经 NET_ERR_RETURN_1) * 限定条件:netTask 上下文 * 函数说明:每 fd 至多一个挂起(禁止覆盖——覆盖丢失前调用方通知 = 该任务永久挂死); * 执行任务自身发起的阻塞等待无他人可完成 → 自等自通知 = 死锁,必须拒绝 */ int net_pending_register(int sockfd, void *buf, int len, uint32_t to_ms, TaskHandle_t caller); /* * 函数功能:挂起 recv 完成检查(netTask 每轮 net_process_messages 调用一次,非阻塞) * 入口参数:p_socks - Socket 控制块表首指针(net_socket.c 的 s_net_socks) net_sock_t * * 出口参数:无 * 返回值:无 * 限定条件:netTask 上下文 * 函数说明:逐 fd 按序判定:①数据到达 ②到点(仅显式预算) ③断连(排空→数据或 * EOF/CONNRESET);命中即经公共出口通知并清槽;另有编译期留痕探针 * (NET_PENDING_TRIPWIRE,默认关) */ void net_pending_tick(net_sock_t *p_socks); /* * 函数功能:清除本 fd 的挂起请求(不通知;"新 fd 不得继承"与 close 后的幂等清理) * 入口参数:sockfd - Socket 描述符 (0~7) int * 出口参数:无 * 返回值:无 * 限定条件:无 */ void net_pending_clear(int sockfd); /* * 函数功能:取消本 fd 的挂起请求并通知调用方(显式路径:对账 resync 等) * 入口参数:sockfd - Socket 描述符 (0~7) int * err - 通知的错误码(如 NET_ERR_CONNRESET) int * 出口参数:无 * 返回值:无(无在位挂起时静默返回) * 限定条件:netTask 上下文 */ void net_pending_cancel(int sockfd, int err); /* * 函数功能:取消全部挂起请求并逐一通知(网络重建路径) * 入口参数:err - 通知的错误码 int * 出口参数:无 * 返回值:无 * 限定条件:netTask 上下文;须在控制块清零与芯片复位之前调用 */ void net_pending_cancel_all(int err); /* * 函数功能:关闭前先结束本 fd 的挂起 recv——有数据先送达(按字节数),无数据则 * 取消(CONNRESET),然后调用方才执行 close/拆会话(per-fd 串行) * 入口参数:sockfd - 将被关闭的描述符 (0~7) int * p_sock - 将被关闭的 Socket 控制块指针(与 sockfd 对应) net_sock_t * * 出口参数:无 * 返回值:无(无在位挂起时静默返回) * 限定条件:netTask 上下文;须在 ch395f_close_socket 之前调用 */ void net_pending_settle_close(int sockfd, net_sock_t *p_sock); /* * 函数功能:查询本 fd 是否有在途挂起 recv —— 宿主能力,供 net_listener 消费 * 入口参数:sockfd - Socket 描述符 (0~7) int * 出口参数:无 * 返回值:1 - 有挂起;0 - 无(含描述符越界) int * 限定条件:任意上下文(纯 RAM 读,不发起 RPC) * 函数说明:N-32 §10 模块化:net_listener_retry_tick 用它跳过"重开 Socket * 会摧毁在途连接"的 fd(挂起 recv 保险) */ int net_pending_active(int sockfd); #endif /* NET_PENDING_H */