【LwIP源码学习4】主线程tcpip_thread

前言

本文对lwip的主要线程tcpip_thread进行分析。

正文

tcpip_thread是lwip最主要的线程,其创建在tcpip_init函数中

sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);

tcpip_init函数被TCPIP_Init函数调用。
TCPIP_Init函数被用户应用程序调用。
在这里插入图片描述
创建任务的sys_thread_new函数在sys_arch.c文件中实现,sys_arch.c是操作系统相关的接口文件,在有操作系统环境下移植lwip时要对sys_arch.c中的函数进行实现。
tcpip_thread任务的内容如下:

static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

  LWIP_MARK_TCPIP_THREAD();

  LOCK_TCPIP_CORE();
  //tcpip_init_done是一个函数指针
  //tcpip_init_done_arg是一个变量指针
  //这两个可以由用户设置,如果想在while循环执行前做些什么
  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  while (1) {                          /* MAIN Loop */
  	//用户可以在opt.h文件中对下面这个宏进行函数定义
  	//可以根据这个宏使得用户在应用层知道tcpip_thread任务还活着
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    //等待邮箱中出现消息、处理超时事件
    TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
    if (msg == NULL) {
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      continue;
    }
    //处理接收到的消息
    tcpip_thread_handle_msg(msg);
  }
}

tcpip_init_done函数指针和tcpip_init_done_arg变量指针在tcpip_init中被设置

void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
...
  tcpip_init_done = initfunc;
  tcpip_init_done_arg = arg;
...
}

而在用户可以修改的sys_arch.c文件中对TCPIP_Init函数的实现:

void TCPIP_Init(void)
{
...
  tcpip_init(NULL, NULL);
...
}

LWIP_TCPIP_THREAD_ALIVE宏在opt.h文件中被定义

#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__
#define LWIP_TCPIP_THREAD_ALIVE()
#endif

如果用于想监测tcpip_thread任务是否一直活着可以在这里进行修改。

TCPIP_MBOX_FETCHtcpip_timeouts_mbox_fetch函数的带参宏定义,用于等待邮箱中是否有需要处理的消息,或者检查是否有超时事件,如果有则执行其回调函数。

static void
tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
  u32_t sleeptime, res;

again:
  LWIP_ASSERT_CORE_LOCKED();
  
  //获取距离最近超时事件的时间
  sleeptime = sys_timeouts_sleeptime();
  if (sleeptime == SYS_TIMEOUTS_SLEEPTIME_INFINITE) {//表示系统没有超时事件
    UNLOCK_TCPIP_CORE();
    //没有超时事件就无限期的一直等待邮箱中有消息到来
    sys_arch_mbox_fetch(mbox, msg, 0);
    LOCK_TCPIP_CORE();
    return;
  } else if (sleeptime == 0) {//表示有超时事件需要立刻执行
    //找出来超时事件并执行其回调函数
    sys_check_timeouts();
    /* We try again to fetch a message from the mbox. */
    //处理完需要立刻执行的超时事件后继续查看最近超时事件时间
    goto again;
  }
  
  //如果系统有超时事件但不还有一段时间触发,就执行以下代码
  UNLOCK_TCPIP_CORE();
  //等到邮箱中是否有消息,等待时间为sleeptime,也就是最近超时事件发生时间
  res = sys_arch_mbox_fetch(mbox, msg, sleeptime);
  LOCK_TCPIP_CORE();
  if (res == SYS_ARCH_TIMEOUT) {//表示邮箱等待超时了,没有等到邮箱中出现新的消息
    /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred
       before a message could be fetched. */
    sys_check_timeouts(); //处理超时事件
    /* We try again to fetch a message from the mbox. */
    goto again; //继续查看是否有超时事件,没有就无限期等邮箱
  }
}

以上这个函数只有在收到邮箱中的一个消息之后才return返回,否则有超时事件就处理超时事件,没有则无限期等待邮箱中出现消息。
思考:似乎有个bug,如果一开始没有超时事件,在无限性等待邮箱中的消息时又出现超时事件了,那么如果一直等不到邮箱中的消息,新出现的超时事件就一直不会被处理了。可能这种情况不会发生,也可能lwip对这种情况有其他处理,还没看到。
其中等待邮箱中出现消息的sys_arch_mbox_fetch函数在sys_arch.c文件中,由用户移植时进行实现。

接下来调用tcpip_thread_handle_msg函数对消息进行分类处理。

static void
tcpip_thread_handle_msg(struct tcpip_msg *msg)
{
  switch (msg->type) {
    case TCPIP_MSG_API:
	...
      break;
    case TCPIP_MSG_API_CALL:
	...
      break;
    case TCPIP_MSG_INPKT:
	...
      break;
    case TCPIP_MSG_TIMEOUT:
	...
      break;
    case TCPIP_MSG_UNTIMEOUT:
	...
      break;
    case TCPIP_MSG_CALLBACK:
	...
      break;
    case TCPIP_MSG_CALLBACK_STATIC:
	...
      break;
    default:
	...
      break;
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908296.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS鸿蒙开发入门,常用ArkUI组件学习(二)

书接上回,让我们继续来学习ArkUI的其他组件 目录,可以点击跳转到想要了解的组件详细内容 组件四:Button组件五:Slider组件六: Column & Row组件七:循环控制组件八: List 组件四:…

四、k8s快速入门之Kubernetes资源清单

kubernetes中的资源 ⭐️ k8s中所有的内容都抽象为资源,资源实列化之后,叫做对象 1️⃣名称空间级别 ⭐️ kubeadm在执行k8s的pod的时候会在kube-system这个名称空间下执行,所以说当你kubectl get pod 的时候是查看不到的查看的是默认的po…

【收藏版】产品经理工作全流程拆解:每一步都是成功的基石

在信息爆炸的今天,产品经理的角色愈加重要。市场分析、用户需求调研、竞品分析、市场定位、产品设计、开发测试……每一个环节都可能决定产品的成败。这篇文章将带你逐步解读从产品立项到上线运营的全流程,为你揭开产品经理的核心工作要点。无论你是新手…

11.1组会汇报-基于区块链的安全多方计算研究现状与展望

基础知识 *1.背书,这个词源来自银行票据业务,是指票据转让时,原持有人在票据背面加盖自己的印鉴,证明该票据真实有效、如果有问题就可以找原持有人。 区块链中的背书就好理解了。可以简单的理解为验证交易并声明此交易合法&…

客如云:大型业务报表的分区化改造提升性能|OceanBase 应用实践

一 概述 1 背景 在过去两到三年的时间里,客如云的KPOS产品在商户数量和订单量均实现了数倍的增长,充分展示了产品的市场吸引力和业务模式的成功。然而,随着更多的大型连锁商户的加入,客如云商家平台迎来了前所未有的挑战。特别是…

一:Linux学习笔记(第一阶段)-- 安装软件 vmware workstation 虚拟机软件 centos系统

目录 学习计划: 资源准备 虚拟机软件:就别自己找了 现在换网站了 下载比较费劲 Centos8: 阿里云镜像地址下载(下载比较版 但是有不同版本):centos安装包下载_开源镜像站-阿里云 百度网盘地址&#xff…

git 删除远程不存在本地命令却能看到的分支

要删除远程不存在但本地却能看到的分支&#xff0c;你可以按照以下步骤操作&#xff1a; 删除本地分支&#xff1a; 如果你确定要删除的分支已经没有用处&#xff0c;可以使用以下命令来删除本地分支&#xff1a; git branch -d <branch-name>这里的 <branch-name>…

为数据集而生的 SQL 控制台

随着数据集的使用量急剧增加&#xff0c;Hugging Face 社区已经变成了众多数据集默认存放的仓库。每月&#xff0c;海量数据集被上传到社区&#xff0c;这些数据集亟需有效的查询、过滤和发现。 Dataset Monthly Creations 每个月在 Hugging Face Hub 创建的数据集 我们现在非常…

城市道路智慧照明服务认证介绍

城市道路智慧照明服务认证介绍 一 认证依据标准 城市道路智慧照明服务认证主要依据《城市道路智慧照明服务评价技术规范》标准&#xff0c;对城市道路照明服务提供商在智慧照明领域的服务质量、技术能力、管理水平等方面&#xff0c;进行综合评估和认证。 二 认证范围 城市道路…

云原生开源开发者沙龙丨AI 应用工程化专场杭州站邀您参会

云原生开源开发者沙龙 AI 原生应用架构专场&#xff0c;邀您一起交流&#xff0c;探索 AI 原生应用的工程化落地&#xff01; 活动简介 AI 驱动的应用程序开发、部署和运维&#xff0c;给应用带来了新的生命力和想象空间。但大部分开发者对 AI 应用的编程框架、可观测体系、网…

Selenium的下载及chrome环境搭建

Selenium的下载及环境的搭建 1.安装python环境 conda 安装python环境《略》2.在CMD在使用pip下载Selenium pip install selenium #pip安装3.下载webdriver 进入Selenium的下载界面&#xff1a;https://www.selenium.dev/downloads/ 下拉找到Browsers 4、驱动与浏览器 ht…

VBA中类的解读及应用第十七讲:类,让文本框在激活时改变颜色(下)

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

JavaCV 图像边缘检测 之 Sobel算子 算法

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

C++ unordered封装

C 哈希-CSDN博客 哈希表是unordered系列容器的底层逻辑&#xff0c;再实现了哈希的底层后&#xff0c;我们按照如下步骤封装unordered: 1. 改变数据类型&#xff0c;将HashTable中的所有的_kv都改成T 2. 因为map需要取key&#xff0c;写一个KeyOfT的仿函数并封装 3. iterator ,…

【Nginx】前端项目开启 Gzip 压缩大幅提高页面加载速度

背景 Gzip 是一种文件压缩算法&#xff0c;减少文件大小&#xff0c;节省带宽从而提减少网络传输时间&#xff0c;网站会更快更丝滑。 // nginx roothcss-ecs-1d22:/etc/nginx# nginx -v nginx version: nginx/1.24.0// node ndde v18.20.1// dependencies "vue": …

在线教育辅助:SpringBoot试题库系统精讲

2 相关技术 2.1 Spring Boot框架简介 Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff0c;Sprin…

【前端基础】CSS基础

目标&#xff1a;掌握 CSS 属性基本写法&#xff0c;能够使用文字相关属性美化文章页。 01-CSS初体验 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#…

操作系统进程的描述与控制知识点

前趋图和程序执行 前趋图 定义&#xff1a; 前趋图是指一个有向无循环图&#xff0c;可记为 DAG&#xff0c;它用于描述进程之间执行的先后顺序图形表示&#xff1a; 程序的执行 程序顺序执行时&#xff0c;系统资源的利用率很低 程序顺序执行时的特征 顺序性封闭性可再现性 …

【观成科技】APT组织常用开源和商业工具加密流量特征分析

概述 在当前的网络安全环境中&#xff0c;APT组织的活动愈发频繁&#xff0c;利用其高级技术和社会工程手段&#xff0c;针对全球范围内的政府、军事和企业目标发起了一系列复杂的网络攻击。在不断升级的攻击中&#xff0c;开源和商业工具凭借其灵活性、易用性和全球化攻击能力…

自杀一句话木马(访问后自动删除)

在做安全测试时&#xff0c;例如文件上传时就要上传可以解析的脚本文件解析证明存在漏洞&#xff0c;这个时候就需要(访问后自动删除文件的一句话木马) PHP <?php echo md5(1);unlink(__FILE__); ?> 访问后自动删除