LWIP之lwip_select函数

2023-05-16

代码如下:

/**
 * Processing exceptset is not yet implemented.
 */
int
lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
            struct timeval *timeout)
{
  u32_t waitres = 0;
  int nready;
  fd_set lreadset, lwriteset, lexceptset;
  u32_t msectimeout;
  struct lwip_select_cb select_cb;
  err_t err;
  int i;
  SYS_ARCH_DECL_PROTECT(lev);

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
                  maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
                  timeout ? (s32_t)timeout->tv_sec : (s32_t)-1,
                  timeout ? (s32_t)timeout->tv_usec : (s32_t)-1));

  /* Go through each socket in each list to count number of sockets which
     currently match */
  nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);

  /* If we don't have any current events, then suspend if we are supposed to */
  if (!nready) {
    if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
      /* This is OK as the local fdsets are empty and nready is zero,
         or we would have returned earlier. */
      goto return_copy_fdsets;
    }

    /* None ready: add our semaphore to list:
       We don't actually need any dynamic memory. Our entry on the
       list is only valid while we are in this function, so it's ok
       to use local variables. */

    select_cb.next = NULL;
    select_cb.prev = NULL;
    select_cb.readset = readset;
    select_cb.writeset = writeset;
    select_cb.exceptset = exceptset;
    select_cb.sem_signalled = 0;
    err = sys_sem_new(&select_cb.sem, 0);
    if (err != ERR_OK) {
      /* failed to create semaphore */
      set_errno(ENOMEM);
      return -1;
    }

    /* Protect the select_cb_list */
    SYS_ARCH_PROTECT(lev);

    /* Put this select_cb on top of list */
    select_cb.next = select_cb_list;
    if (select_cb_list != NULL) {
      select_cb_list->prev = &select_cb;
    }
    select_cb_list = &select_cb;
    /* Increasing this counter tells even_callback that the list has changed. */
    select_cb_ctr++;

    /* Now we can safely unprotect */
    SYS_ARCH_UNPROTECT(lev);

    /* Increase select_waiting for each socket we are interested in */
    for(i = 0; i < maxfdp1; i++) {
      if ((readset && FD_ISSET(i, readset)) ||
          (writeset && FD_ISSET(i, writeset)) ||
          (exceptset && FD_ISSET(i, exceptset))) {
        struct lwip_sock *sock = tryget_socket(i);
        LWIP_ASSERT("sock != NULL", sock != NULL);
        SYS_ARCH_PROTECT(lev);
        sock->select_waiting++;
        LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
        SYS_ARCH_UNPROTECT(lev);
      }
    }

    /* Call lwip_selscan again: there could have been events between
       the last scan (whithout us on the list) and putting us on the list! */
    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
    if (!nready) {
      /* Still none ready, just wait to be woken */
      if (timeout == 0) {
        /* Wait forever */
        msectimeout = 0;
      } else {
        msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
        if (msectimeout == 0) {
          /* Wait 1ms at least (0 means wait forever) */
          msectimeout = 1;
        }
      }

      waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout);
    }
    /* Increase select_waiting for each socket we are interested in */
    for(i = 0; i < maxfdp1; i++) {
      if ((readset && FD_ISSET(i, readset)) ||
          (writeset && FD_ISSET(i, writeset)) ||
          (exceptset && FD_ISSET(i, exceptset))) {
        struct lwip_sock *sock = tryget_socket(i);
        LWIP_ASSERT("sock != NULL", sock != NULL);
        SYS_ARCH_PROTECT(lev);
        sock->select_waiting--;
        LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0);
        SYS_ARCH_UNPROTECT(lev);
      }
    }
    /* Take us off the list */
    SYS_ARCH_PROTECT(lev);
    if (select_cb.next != NULL) {
      select_cb.next->prev = select_cb.prev;
    }
    if (select_cb_list == &select_cb) {
      LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL);
      select_cb_list = select_cb.next;
    } else {
      LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL);
      select_cb.prev->next = select_cb.next;
    }
    /* Increasing this counter tells even_callback that the list has changed. */
    select_cb_ctr++;
    SYS_ARCH_UNPROTECT(lev);

    sys_sem_free(&select_cb.sem);
    if (waitres == SYS_ARCH_TIMEOUT)  {
      /* Timeout */
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
      /* This is OK as the local fdsets are empty and nready is zero,
         or we would have returned earlier. */
      goto return_copy_fdsets;
    }

    /* See what's set */
    nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
  }

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
return_copy_fdsets:
  set_errno(0);
  if (readset) {
    *readset = lreadset;
  }
  if (writeset) {
    *writeset = lwriteset;
  }
  if (exceptset) {
    *exceptset = lexceptset;
  }


  return nready;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LWIP之lwip_select函数 的相关文章

随机推荐

  • Vuex速学篇:(1)基本套路

    我们前面做了一个这样的页面 xff0c 为了增加我们的学习难度 xff0c 我们特意拆分成了不同的组件 我们知道 xff0c 我们在子组件里并不能直接对兄弟组件里的属性进行操作 xff0c 我们通过this emit 调用父组件的方法 xf
  • ElementUI案例演示:导航、布局、加载动画

    知识点 1 vue router之嵌套路由 http router vuejs org zh cn essentials nested routes html 2 element ui 导航组件 布局组件 加载动画 http element
  • ElementUI之表单验证、数据绑定、路由跳转

    1 新建表单组件el form vue span class hljs tag lt span class hljs title template span gt span span class hljs tag lt span class
  • vue-router: 嵌套路由

    模板抽离 我们已经学习过了Vue模板的另外定义形式 xff0c 使用 lt template gt lt template gt span class hljs comment lt 模板抽离出来 gt span span class hl
  • react.js的两种路由方式:HashRouter

    react js路由 初步 前面我们已经了解了react js其中一种路由方式 这种方式是利用 html5的 span class hljs escape 96 w span indow history span class hljs es
  • 入手python绘图包:matplotlib,画直线、画抛物线

    入手python绘图包 xff1a matplotlib 官方地址 xff1a http matplotlib org github地址 xff1a http github com matplotlib matplotlib 学习一款图形化
  • 使用CMake构建OpenCV项目

    上一篇文章中 xff0c 我们介绍了如何在ubuntu上安装配置OpenCV xff0c 这篇文章我们来对我们的安装进行测试 xff0c 并介绍如何用CMake工具快捷地构建OpenCV项目 项目结构 为了使整个项目更加条理 xff0c 我
  • Ubuntu连接不了网络的解决方法亲测可行经验

    突然发现Ubuntu连不上网络 xff0c 网络打问号或者右上角也没有网络图标 xff1b 楼主一般通过前两步就解决了 xff0c 大家自行查阅网络服务名称 xff0c OK直接进入正题 通过命令行方式重启网络 如果你使用的 Ubuntu
  • 解决 ImportError: C extension: No module named ‘pandas._libs.tslib‘ not built.

    yolo配置 报错 nvidia 64 nx yolov5 master python3 detect py Traceback most recent call last File 34 usr lib python3 dist pack
  • python subprocess获取stdout和stderr

    本文转载自http www firefoxbug com index php archives 2419 xff0c 如有版权问题请联系博主删除 用subprocess的时候 xff0c 怎么获取stdout和stderr xff1f 下面
  • 关于Libcurl双向认证请求https

    之前通过libcurl开发只是做http请求 xff0c 这次公司项目需要请求https xff0c 所以就研究了一下 xff0c 其实用libcurl做http请求是非常简单的 xff0c 所有底层实现都被封装到了libcurl里面 xf
  • Kubernates简介

    Kubernates简介 应用程序的开发部署变化 从单体应用到微服务 单体应用的缺点 由多个彼此耦合的组件组成 开发 部署 管理必须以同一个实体进行 即使对某个组件的小修改也需要重新部署整个应用 组件之间没有严格的边界定义 相互依赖 随着功
  • pipenv 无法获取系统环境变量

    今天遇到了一个有意思的问题 项目是使用pipenv作为虚环境来进行包管理的 xff0c 今天在windows server 2012R2和windows server 2016上发现python脚本在运行的过程中 xff0c 不能读取到系统
  • 创客基地oDrive第二课 X2212电机配置

    淘宝套装链接 B站视频链接 2021年3月31日前 入Q群 xff08 732557609 xff09 可抽奖oDrive主板 xff01 B站视频 创客基地oDrive第二课 X2212电机配置 第1部分 硬件介绍 1 1 硬件清单 oD
  • Makerbase X2212电流环(转矩)配置

    该配置基于X2212电机 xff0c 控制模式为电流环 xff08 转矩 xff09 模式 主板参数 电机参数 编码器参数配置和位置环控制一样 xff0c 已配置可直接跳转到控制器配置 xff0c 没有配置的按以下步骤配置 1 恢复默认参数
  • Postman -中文版-安装教程

    一 下载 安装 Postman 下面是历史版本的下载链接地址 请把链接中的 34 版本号 34 替换为指定的版本号 xff08 根据自己的需求变更 xff09 Windows64位 xff1a https dl pstmn io downl
  • HTTP Digest authentication

    Digest authentication xff09 是一个简单的认证机制 xff0c 最初是为 HTTP 协议开发的 xff0c 因而也常叫做 HTTP 摘要 xff0c 在 RFC2671 中描述 其身份验证机制很简单 xff0c 它
  • ubuntu离线安装Gcc、G++、Make

    前期准备 xff1a 由于GCC G 43 43 Make等工具依赖项众多 xff0c 我们需要提前先把基础依赖库下载并安装 xff0c 才能安装以上工具 工具安装包或基础依赖库下载参加以下Ubuntu官网链接 xff1a xff08 注意
  • 教你轻松在Ubuntu 部署yolov5,胎儿级教程

    环境 xff1a Jetson xavier nx Ubuntu 18 04 python3 8 一 yolov5安装 git clone https codechina csdn net mirrors ultralytics yolov
  • LWIP之lwip_select函数

    代码如下 xff1a Processing exceptset is not yet implemented int lwip select int maxfdp1 fd set readset fd set writeset fd set