X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/45636487143097d360dfba4f3fa602b08927e355..c086b85afb1f0f2d9aa76faa5a4c8536380670a2:/doc/RedisEventLibrary.html diff --git a/doc/RedisEventLibrary.html b/doc/RedisEventLibrary.html new file mode 100644 index 00000000..4b641a3c --- /dev/null +++ b/doc/RedisEventLibrary.html @@ -0,0 +1,70 @@ + + + +
+ + + +initServer
function defined in redis.c initializes the numerous fields of the redisServer
structure variable. One such field is the Redis event loop el
:+aeEventLoop *el +
initServer
initializes server.el
field by calling aeCreateEventLoop
defined in ae.c. The definition of aeEventLoop
is below:
++typedef struct aeEventLoop +{ + int maxfd; + long long timeEventNextId; + aeFileEvent events[AE_SETSIZE]; /* Registered events */ + aeFiredEvent fired[AE_SETSIZE]; /* Fired events */ + aeTimeEvent *timeEventHead; + int stop; + void *apidata; /* This is used for polling API specific data */ + aeBeforeSleepProc *beforesleep; +} aeEventLoop; +
aeCreateEventLoop
first mallocs aeEventLoop structure then calls ae_epoll.c:aeApiCreate.
+
+
aeApiCreate mallocs
aeApiState that has two fields -
epfd that holds the epoll file descriptor returned by a call from [http://man.cx/epoll_create%282%29 epoll_create] and
events that is of type
struct epoll_event define by the Linux epoll library. The use of the
events field will be described later.
+
+Next is 'ae.c:aeCreateTimeEvent
. But before that initServer
call anet.c:anetTcpServer
that creates and returns a listening descriptor. The descriptor is listens to port 6379 by default. The returned listening descriptor is stored in server.fd
field.aeCreateTimeEvent
accepts the following as parameters:server.el
in redis.cinitServer
calls aeCreateTimeEvent
to add a timed event to timeEventHead
field of server.el
. timeEventHead
is a pointer to a list of such timed events. The call to aeCreateTimeEvent
from redis.c:initServer
function is given below:+aeCreateTimeEvent(server.el /*eventLoop*/, 1 /*milliseconds*/, serverCron /*proc*/, NULL /*clientData*/, NULL /*finalizerProc*/); +
redis.c:serverCron
performs many operations that helps keep Redis running properly.aeCreateFileEvent
function is to execute epoll_ctl system call which adds a watch for EPOLLIN
event on the listening descriptor create by anetTcpServer
and associate it with the epoll descriptor created by a call to aeCreateEventLoop
. aeCreateFileEvent
does when called from redis.c:initServer
.initServer
passes the following arguments to aeCreateFileEvent
:
+aeCreateEventLoop
. The epoll descriptor is got from server.el. eventLoop->events
table and store extra information like the callback function.eventLoop->events[server.fd]->rfileProc
. ae.c:aeMain
called from redis.c:main
does the job of processing the event loop that is initialized in the previous phase.ae.c:aeMain
calls ae.c:aeProcessEvents
in a while loop that processes pending time and file events.ae.c:aeProcessEvents
looks for the time event that will be pending in the smallest amount of time by calling ae.c:aeSearchNearestTimer
on the event loop. In our case there is only one timer event in the event loop that was created by ae.c:aeCreateTimeEvent
. aeCreateTimeEvent
has by now probably elapsed because it had a expiry time of one millisecond. Since, the timer has already expired the seconds and microseconds fields of the tvp
timeval structure variable is initialized to zero. tvp
structure variable along with the event loop variable is passed to ae_epoll.c:aeApiPoll
.aeApiPoll
functions does a epoll_wait on the epoll descriptor and populates the eventLoop->fired
table with the details:
+aeApiPoll
returns the number of such file events ready for operation. Now to put things in context, if any client has requested for a connection then aeApiPoll would have noticed it and populated the eventLoop->fired
table with an entry of the descriptor being the listening descriptor and mask being AE_READABLE
.aeProcessEvents
calls the redis.c:acceptHandler
registered as the callback. acceptHandler
executes [http://man.cx/accept(2) accept] on the listening descriptor returning a connected descriptor with the client. redis.c:createClient
adds a file event on the connected descriptor through a call to ae.c:aeCreateFileEvent
like below:+ if (aeCreateFileEvent(server.el, c->fd, AE_READABLE, + readQueryFromClient, c) == AE_ERR) { + freeClient(c); + return NULL; + } +
c
is the redisClient
structure variable and c->fd
is the connected descriptor.ae.c:aeProcessEvent
calls ae.c:processTimeEvents
ae.processTimeEvents
iterates over list of time events starting at eventLoop->timeEventHead
.processTimeEvents
calls the registered callback. In this case it calls the only timed event callback registered, that is, redis.c:serverCron
. The callback returns the time in milliseconds after which the callback must be called again. This change is recorded via a call to ae.c:aeAddMilliSeconds
and will be handled on the next iteration of ae.c:aeMain
while loop.