Skip to content

Socket::OnInputEventfd=-1 时 CHECK 失败 (Revive 机制) #3492

Description

@condy0919

Describe the bug

一个猜测的时序如下

  • 线程1: RPC 请求中,但是 SetFailed 发生,版本号+1
  • 线程2: 过了 100ms 后,健康检查任务启动
  • 线程3: EventDispatcher 上收到了这个 fd 上的 EPOLLIN | EPOLLRDHUP 事件,对端关闭了。准备遍历 epoll_event 数组,但是很不巧被 OS 调度切走了
  • 线程2: 健康检查 WaitAndReset 里将 fd 关闭,并令 fd=-1. 之后探测成功,再调用 Revive 将版本号复原,但是 fd=-1
  • 线程3: 执行 OnInputEvent, 因为 Revive 恢复了版本号 Address 成功,但是它检测了 s->fd() == -1 时再比较一下 events 里是否有 EPOLLIN. 但是这个 EPOLLIN 事件明显是过期的,因为之前的 fd 已经被其他原因 SetFailed

看日志表现是这样,因为日志中存在大量的 Checking ... Revived ... 健康检查相关的打印,且网络非常不稳定。

如果是这种原因的话,似乎

    if (s->fd() < 0) {
#if defined(OS_LINUX)
        CHECK(!(events & EPOLLIN)) << "epoll_events=" << events;
#elif defined(OS_MACOSX)
        CHECK((short)events != EVFILT_READ) << "kqueue filter=" << events;
#endif
        return -1;
    }

中的断言可以去掉?

@chenBright

Versions
OS: openeuler 24.03sp3
Compiler: gcc14
brpc: 1.17

Additional context/screenshots

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions