相关资料
redis.c
networking.c
1. 建立连接
/* Create an event handler for accepting new connections in TCP and Unix
* domain sockets. */
for (j = 0; j < server.ipfd_count; j++) {
if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,
acceptTcpHandler,NULL) == AE_ERR)
{
redisPanic(
"Unrecoverable error creating server.ipfd file event.");
}
}
if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
acceptUnixHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.sofd file event.");
当客户端请求连接时,对应的事件处理函数是:acceptTcpHandler、acceptUnixHandler,其中:
acceptTcpHandler 接受 tcp 连接请求;
acceptUnixHandler 接受 unix 域连接请求。
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
char cip[REDIS_IP_STR_LEN];
REDIS_NOTUSED(el);
REDIS_NOTUSED(mask);
REDIS_NOTUSED(privdata);
while(max--) {
cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
if (cfd == ANET_ERR) {
if (errno != EWOULDBLOCK)
redisLog(REDIS_WARNING,
"Accepting client connection: %s", server.neterr);
return;
}
redisLog(REDIS_VERBOSE,"Accepted %s:%d", cip, cport);
acceptCommonHandler(cfd,0);
}
}
anetTcpAccept 接受 tcp 连接,同时返回连接套接字cfd。
acceptCommonHandler 对连接套接字cfd及对应的客户端结构进行初始化。
c = createClient(fd))
初始化主要在 createClient 函数中进行,其中,通过注册事件处理函数 readQueryFromClient 来读取请求。
aeCreateFileEvent(server.el,fd,AE_READABLE,readQueryFromClient, c)
2. 请求处理
请求处理可以分为3个步骤:
1. 读取请求
2. 解析请求
3. 执行请求
readQueryFromClient 函数是请求处理的起点,该函数将请求读取到 c->querybuf 中,然后调用 processInputBuffer 函数。
void processInputBuffer(redisClient *c) {
/* Keep processing while there is something in the input buffer */
while(sdslen(c->querybuf)) {
/* Immediately abort if the client is in the middle of something. */
if (c->flags & REDIS_BLOCKED) return;
/* REDIS_CLOSE_AFTER_REPLY closes the connection once the reply is
* written to the client. Make sure to not let the reply grow after
* this flag has been set (i.e. don't process more commands). */
if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;
/* Determine request type when unknown. */
if (!c->reqtype) {
if (c->querybuf[0] == '*') {
c->reqtype = REDIS_REQ_MULTIBULK;
} else {
c->reqtype = REDIS_REQ_INLINE;
}
}
if (c->reqtype == REDIS_REQ_INLINE) {
if (processInlineBuffer(c) != REDIS_OK) break;
} else if (c->reqtype == REDIS_REQ_MULTIBULK) {
if (processMultibulkBuffer(c) != REDIS_OK) break;
} else {
redisPanic("Unknown request type");
}
/* Multibulk processing could see a <= 0 length. */
if (c->argc == 0) {
resetClient(c);
} else {
/* Only reset the client when the command was executed. */
if (processCommand(c) == REDIS_OK)
resetClient(c);
}
}
}
if (c->reqtype == REDIS_REQ_INLINE) {
if (processInlineBuffer(c) != REDIS_OK) break;
} else if (c->reqtype == REDIS_REQ_MULTIBULK) {
if (processMultibulkBuffer(c) != REDIS_OK) break;
}
根据请求类型,分别调用 processInlineBuffer 和 processMultibulkBuffer 解析请求。
最后调用 processCommand 函数执行请求。
c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr);
根据argv[0],查找CommandTable,找到对应的执行函数。
call(c,REDIS_CALL_FULL);
调用函数执行命令。
看的我热血沸腾啊
哈哈哈,写的太好了https://www.cscnn.com/
《街角少年第四季》欧美综艺高清在线免费观看:https://www.jgz518.com/xingkong/36667.html
《吉米霍法之死》记录片高清在线免费观看:https://www.jgz518.com/xingkong/60147.html
博主太厉害了!
《戴帽子的猫》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/34719.html
《包豪斯时代》欧美剧高清在线免费观看:https://www.jgz518.com/xingkong/149560.html
《罗丹2017》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/165441.html