Linux epoll 源码分析 3

Posted 底层技术研究

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux epoll 源码分析 3相关的知识,希望对你有一定的参考价值。

在上一篇文章 Linux epoll 源码分析 2 中,我们分析了 epoll_ctl 的 ep_insert 方法,在这里我们继续看下 ep_remove 和 ep_modify 方法。


我们先看下 ep_remove 方法


// fs/eventpoll.c

static int ep_remove(struct eventpoll *ep, struct epitem *epi)

{

  ...

  struct file *file = epi->ffd.file;

  ...

  // 将epitem从tcp socket的事件变动通知队列中移除

  ep_unregister_pollwait(ep, epi);

  ...

  // 从eventpoll中的红黑树数据结构中移除

  rb_erase_cached(&epi->rbn, &ep->rbr);

  ...

  // 如果epitem在eventpoll的rdllist队列中,也移除

  if (ep_is_linked(&epi->rdllink))

    list_del_init(&epi->rdllink);

  ...

  return 0;

}


再看下ep_modify 方法


static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event)

{

  ...

  epi->event.events = event->events;

  epi->event.data = event->data;

  ...

  revents = ep_item_poll(epi, &pt, 1);

  ...

  if (revents & event->events) 

    ...

    if (!ep_is_linked(&epi->rdllink)) {

      list_add_tail(&epi->rdllink, &ep->rdllist);

      ...

      if (waitqueue_active(&ep->wq))

        wake_up_locked(&ep->wq);

      ...

    }

    spin_unlock_irq(&ep->lock);

  }

  ...

  return 0;

}


该方法的逻辑和ep_insert方法里的逻辑比较像,它先覆盖epitem中epoll_event的旧值,然后检查该文件当前已经就绪的事件,如果这些事件中有我们感兴趣的事件,则把epitem放到eventpoll的rdllist队列中,最后通知因调用epoll_wait堵塞的线程,它们可以继续执行了。


至此,epoll的所有逻辑都已讲完。


有关tcp在何种情况下,会通知给epoll何种事件,我们会在其他文章中详细讲解。

以上是关于Linux epoll 源码分析 3的主要内容,如果未能解决你的问题,请参考以下文章

Linux epoll 源码分析 2

Linux epoll模型详解及源码分析

Linux epoll模型详解及源码分析

epoll源码分析(基于linux-5.1.4)

面试必问的epoll技术,从内核源码出发彻底搞懂epoll

「底层原理」epoll源码分析,还搞不懂epoll的看过来