perf: replace select with epoll in mbd/sbd/lim modules #43
+617
−93
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The core goal of this code change is to introduce the high-performance
epollIO event-driven mechanism, refactor the channel event management logic, achieve high efficiency and stability in server-side IO event processing, and complete the adaptation of all components to the new mechanism.1. Header File Changes (
lib.channel.h,lsf.h,lim.h)1.1
lib.channel.h: Interface Definition for Channel and epoll Mechanism(1) New Event Type Enumeration
Define the standardized channel ready event enumeration
epoll_events_tto achieve unified management of event states(2) Structure Field Extension
struct chanData: Add thelistenEvents(recording the listening event mask registered by the channel in epoll) andreadyEvents(marking the current ready event status of the channel) fields to realize decoupled management of listening events and ready states.(3) New Error Code
Add the
CHANE_EPOLLFAILerror code (value 12) to specifically identify the execution failure of epoll-related system calls.(4) Core Function Declarations
epoll Environment Initialization and Destruction:
chanEpollInit(): Initialize the epoll instance, event array and channel status, which must be called before creating listening sockets.chanCloseEpoll(): Close the epoll file descriptor and reset the running state to avoid resource conflicts between processes.epoll Event Loop:
chanEpoll_(int **, struct timeval *timeout): Implement epoll event monitoring and ready channel filtering, return the number of ready channels and output the channel index array.Channel Event Registration and Update:
chanRegisterEpoll_(int, uint32_t): Register the channel to epoll and bind listening events.chanUpdateListenEvents(int, uint32_t): Dynamically update the epoll listening event mask of the channel.chanUnRegisterEpoll_(int): Deregister the channel from epoll and clean up invalid listening.Ready Event Query and Management:
chanEventsReady(int chfd, int events): Verify whether the specified channel has target ready events.chanQuitReadyEvents(int chfd, int events): Clear the specified ready event status of the channel.Data Enqueue Interface Adjustment:
chanEnqueue_(int chfd, struct Buffer *buf, int needUpdateEvent)adds theneedUpdateEventparameter to control whether to trigger dynamic registration of epoll write events after data enqueuing.1.2
lsf.h: Basic Dependency SupplementInclude the
<sys/epoll.h>header file to provide interface support for epoll-related system calls and ensure compilation compatibility.1.3
lim.h: LIM Service Interface AdaptationAdjust the
clientIOfunction signature tovoid clientIO(int *, int), with parameters being the ready channel index array and the number of channels, adapting to the event traversal logic under the epoll mechanism.2. Source File Changes (
lib.channel.c,mbd.main.c,sbd.main.c,lim.main.c, etc.)2.1
lib.channel.c: Core Implementation of the epoll Mechanism(1) Global Resources and Initialization
Add global variables such as
epollfd(epoll instance file descriptor),epoll_events(epoll event array),readyChans(ready channel index array), andchanEpollListenEventUpdateOn(epoll function switch) to realize global management of epoll resources.Implement the
chanEpollInitfunction: Create an epoll instance throughepoll_create1(EPOLL_CLOEXEC), allocate event array memory, initialize thelistenEventsandreadyEventsstates of all channels, and enable the epoll function switch.(2) epoll Event Loop Logic
Implement the
chanEpoll_function to complete event monitoring, ready state conversion and ready channel filtering:Clear historical ready events through
chanClearReadyEventsbefore calling to avoid state residue;Call
epoll_waitto obtain ready events and convert system events into thereadyEventsstate of the channel;Automatically trigger
doreadEpoll/dowriteEpollfor channels with buffers to complete data reading and writing;Filter out ready channels that need upper-layer processing, fill the
readyChansarray and return the number of channels.(3) Channel Event Registration and Management
chanRegisterEpoll_: Called in scenarios such aschanServSocket_(listening socket creation) andchanOpenSock_(connected socket encapsulation), register the channel socket to epoll throughepoll_ctl(EPOLL_CTL_ADD)and bind the channel index.chanUpdateListenEvents: Called in scenarios such aschanEnqueue_(needing to monitor write events after data enqueuing) anddowriteEpoll(canceling write events after sending is completed), dynamically update the listening event mask throughepoll_ctl(EPOLL_CTL_MOD).chanUnRegisterEpoll_: Called in thechanClose_(channel closing) scenario, deregister the channel from epoll throughepoll_ctl(EPOLL_CTL_DEL)and clean up invalid listening.(4) Socket Read/Write Logic Adaptation
doreadEpoll: Implement socket read logic based on epoll, complete buffer allocation, protocol header parsing, data reception and buffer expansion, and mark the channel read-ready state after data reception is completed.dowriteEpoll: Implement socket write logic based on epoll, complete data sending, automatically cancel write event monitoring according to the buffer state after sending.(5) Channel Status and Resource Cleanup Optimization
CLOSEITmacro enhancement: Reset the channelreadyEventsstate synchronously when closing the socket to ensure a clean channel state.chanClose_function extension: Automatically deregister the channel from epoll when closing the channel to avoid invalid resource occupation.2.2
mbd.main.candsbd.main.c: Server Main Process Adaptation(1) Initialization Process Enhancement
In the business initialization phase of the main function
main(beforeminit/sinit), add a call tochanEpollInit()to complete the pre-initialization of the epoll environment.(2) Event Loop Reconstruction
fd_setandstruct Masks, and replace them withchanEpoll_calls to obtain the ready channel array;(3)
clientIOFunction AdaptationSimplify the function signature to the parameterless form
clientIO(), no longer relying on event mask parameter passing;Event judgment logic: Use
chanEventsReadyinstead ofFD_ISSETto judge the channel ready state, exception events (EPOLL_EVENTS_ERROR) trigger client connection closing, and read events (EPOLL_EVENTS_READ) trigger request processing;Call
chanQuitReadyEventsto clear the read-ready state after read event processing to avoid repeated processing.2.3
lim.main.candlim.cluster.c: LIM Service Adaptation(1) Event Acquisition in the Main Loop
Remove variables related to
struct Masks, obtain thereadyChansready channel array throughchanEpoll_, replacing the traditional event mask mechanism.(2)
clientIOFunction Logic AdjustmentReceive the
readyChansarray and the number of ready channels as parameters, traverse ready channels instead of all channels to improve processing efficiency;Judge the channel event state through
chanEventsReady, exception events triggershutDownChanto clean up the channel, and read events triggerprocessMsgto process requests.(3) Parent-Child Process Resource Isolation
After forking a child process (such as a request processing child process), call
chanCloseEpoll()to close the inherited epoll file descriptor to prevent epoll operations of the child process from affecting the parent process's listening logic.