设为首页 加入收藏

TOP

redis启动过程源码解析(三)
2019-09-17 18:41:58 】 浏览:83
Tags:redis 启动 过程 源码 解析
meout, eviction of unaccessed
83 * expired keys and so forth. */ 84 //创建时间事件,1ms调用serverCron 85 if (aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) { 86 serverPanic("Can't create event loop timers."); 87 exit(1); 88 } 89 90 /* Create an event handler for accepting new connections in TCP and Unix 91 * domain sockets. */ 92 //设定套接字可读可写状态的处理函数 93 for (j = 0; j < server.ipfd_count; j++) { 94 if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, 95 acceptTcpHandler,NULL) == AE_ERR) 96 { 97 serverPanic( 98 "Unrecoverable error creating server.ipfd file event."); 99 } 100 } 101 }

  listenToPort函数会对所有配置需要监听的ip地址和端口调用_anetTcpServer函数(anet.c), _anetTcpServer函数源码如下,1-17行建立socket套接字s,23行调用函数anetListen完成服务端socket的bind和listen。

 1 static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog)
 2 {
 3     int s = -1, rv;
 4     char _port[6];  /* strlen("65535") */
 5     struct addrinfo hints, *servinfo, *p;
 6     snprintf(_port,6,"%d",port);
 7     memset(&hints,0,sizeof(hints));
 8     hints.ai_family = af;
 9     hints.ai_socktype = SOCK_STREAM;
10     hints.ai_flags = AI_PASSIVE;    /* No effect if bindaddr != NULL */
11 
12     if ((rv = getaddrinfo(bindaddr,_port,&hints,&servinfo)) != 0) {
13         anetSetError(err, "%s", gai_strerror(rv));
14         return ANET_ERR;
15     }
16     for (p = servinfo; p != NULL; p = p->ai_next) {
17         if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
18             continue;
19 
20         if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
21         if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
22         //anetListen调用listen和bind
23         if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
24         goto end;
25     }
26     if (p == NULL) {
27         anetSetError(err, "unable to bind socket, errno: %d", errno);
28         goto error;
29     }
30 
31 error:
32     if (s != -1) close(s);
33     s = ANET_ERR;
34 end:
35     freeaddrinfo(servinfo);
36     return s;
37 }

  anetListen函数源码如下:

 1 static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
 2     if (bind(s,sa,len) == -1) {
 3         anetSetError(err, "bind: %s", strerror(errno));
 4         close(s);
 5         return ANET_ERR;
 6     }
 7 
 8     if (listen(s, backlog) == -1) {
 9         anetSetError(err, "listen: %s", strerror(errno));
10         close(s);
11         return ANET_ERR;
12     }
13     return ANET_OK;
14 }

  在分析aeCreateTimeEvent和aeCreateFileEvent函数之前,先给出server中的aeEventLoop类型变量el结构体定义(ae.h):

/* File event structure */
//文件事件结构体
typedef struct aeFileEvent {
    ////读或者写,也用于标识该事件结构体是否正在使用
    int mask; /* one of AE_(READABLE|WRITABLE|BARRIER) */
    //读事件的处理函数
    aeFileProc *rfileProc;
    //写事件的处理函数
    aeFileProc *wfileProc;
    //传递给上述两个函数的数据
    void *clientData;
} aeFileEvent;

/* Time event structure */
//时间事件
typedef struct aeTimeEvent {
    //时间事件标识符,用于唯一标识该时间事件,并且用于删除时间事件
    long long id; /* time event identifier. */
    long when_sec; /* seconds */
    long when_ms; /* milliseconds */
    //事件对应的处理程序
    aeTimeProc *timeProc;
    //时间事件的最后一次处理程序,若已设置,则删除时间事件时会被调用
    aeEventFinalizerProc *finalizerProc;
    void *clientData;
    struct aeTimeEvent *prev;
    struct aeTimeEvent *next;
} aeTimeEvent;

/* A fired event */
//用于保存已触发的事件
typedef struct aeFiredEvent {
    int fd;
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇CentOS7.3安装mysql数据库 下一篇DBA_OBJECTS

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目