Prior to summarizing the Redis communication process, the basic framework, Epoll encapsulation and so on, this introduction
Redis encapsulation of the Select model
// Select Model struct aeapistate { // Read file descriptor set, write file descriptor set fd_set RfDs, Wfds; /* We need to has a copy of the FD sets as it 's not safe to reuse */ // copy of Read-write collection fd_set _rfds, _wfds;} aeapistate;
_rfds and _wfds are copies of both read and write, because the select call will read and write to the file descriptor in the collection that is not ready
Clear, so each time with _rfds and _wfds incoming, do not worry about the original read and write set descriptor is cleared.
Encapsulated select-based initialization function
static int aeapicreate ( Aeeventloop *eventloop) { Open aeapistate space aeapistate *state = Zmalloc (sizeof (aeapistate)); if (!state) return -1 ; // Read and write set 0 Fd_zero (&state- >rfds); Fd_zero ( &state->wfds); EventLoop ->apidata = State; return 0 ;}
The function zeros the read-write collection and passes the state back to the apidata part of EventLoop.
Memory Reclamation Features
// Free Space Static void aeapifree (aeeventloop *eventloop) { zfree (eventloop);}
Encapsulation of Add and delete events
//Select Add EventStatic intAeapiaddevent (Aeeventloop *eventloop,intFdintmask) {Aeapistate*state = eventloop->Apidata; if(Mask & ae_readable) Fd_set (fd,&state->RFDS); if(Mask & ae_writable) Fd_set (fd,&state->Wfds); return 0;}//Select Delete EventStatic voidAeapidelevent (Aeeventloop *eventloop,intFdintmask) {Aeapistate*state = eventloop->Apidata; if(Mask & ae_readable) FD_CLR (fd,&state->RFDS); if(Mask & ae_writable) FD_CLR (fd,&state->Wfds);}
Add an event function to put the file description according to whether the mask is a read event or a write event into a different set
The Delete event is purged from a different set based on whether the file descriptor mask is a read event or a write event
Here is the core function, event dispatch
//Select Trigger EventStatic intAeapipoll (Aeeventloop *eventloop,structTimeval *TVP) {Aeapistate*state = eventloop->Apidata; intRetVal, J, numevents =0; //Copy the data from the select Read collection to the _rfdsmemcpy (&state->_rfds,&state->rfds,sizeof(Fd_set)); //Copy Select Write collection data to _wfdsmemcpy (&state->_wfds,&state->wfds,sizeof(Fd_set)); //Select a ready file descriptor from the Copy collection read and writeretval =Select(eventloop->maxfd+1, &state->_rfds,&state->_WFDS,NULL,TVP); //greater than 0 indicates a ready file descriptor if(RetVal >0) { //The disadvantage of select is that all file descriptors are polled once each time for(j =0; J <= eventloop->maxfd; J + +) { intMask =0; Aefileevent*fe = &eventLoop->Events[j]; if(Fe->mask = = Ae_none)Continue; //aefileevent Event readable if(Fe->mask & ae_readable && fd_isset (j,&state->_rfds)) Mask|=ae_readable; //aefileevent events can be written if(Fe->mask & ae_writable && fd_isset (j,&state->_wfds)) Mask|=ae_writable; EventLoop->FIRED[NUMEVENTS].FD =J; EventLoop->fired[numevents].mask =Mask; Numevents++; } } returnnumevents;}
The _rfds and _wfds of the contents of the read-write collection are first passed into the Select function, respectively.
This allows only the ready read socket in the _RFDS returned by the Select
Only ready-to-write sockets in _wfds
Fd_isset to the EventLoop fire queue after judging the read and write events.
The basic package is this way, and the select model is relatively easy to understand
My public number:
Understanding of the Redis underlying framework (v)