// 判断超时,并作超时的处理 void luaMaskCountHook(lua_State *lua, lua_Debug *ar) { long long elapsed; REDIS_NOTUSED(ar); REDIS_NOTUSED(lua); // 计算已经超时的时间 elapsed = (ustime()/1000) - server.lua_time_start; if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) { redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed); server.lua_timedout = 1; // 超时了,关闭监听发送 lua 脚本命令的客户端 /* Once the script timeouts we reenter the event loop to permit others * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason * we need to mask the client executing the script from the event loop. * If we don't do that the client may disconnect and could no longer be * here when the EVAL command will return. */ aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE); } // lua 脚本执行超时,redis 会检测对否有其他客户端会发送 SCRIPT KILL 命令 // 尝试终结这个脚本的执行 if (server.lua_timedout) aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT); // 如果 lua 脚本被停止了,强制产生错误,结束 lua if (server.lua_kill) { redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL."); lua_pushstring(lua,"Script killed by user with SCRIPT KILL..."); lua_error(lua); } }
void evnet_loop(unsigned int loops) { if(NULL != g_libnet.evLoop){ aeProcessEvents(g_libnet.evLoop); } channel_crond(loops); }
void aeMain(aeEventLoop*eventLoop) { eventLoop->stop=0; while(!eventLoop->stop){ aeProcessEvents(eventLoop,AE_ALL_EVENTS); } }
/* * 脚本超时钩子 */ void luaMaskCountHook(lua_State *lua, lua_Debug *ar) { long long elapsed; REDIS_NOTUSED(ar); REDIS_NOTUSED(lua); // 计算已执行时间 elapsed = (ustime()/1000) - server.lua_time_start; if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) { redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed); // 已超时 server.lua_timedout = 1; /* Once the script timeouts we reenter the event loop to permit others * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason * we need to mask the client executing the script from the event loop. * If we don't do that the client may disconnect and could no longer be * here when the EVAL command will return. */ // 当脚本运行超时时,将正在执行的客户端从读事件中移除 // 并允许其他客户端执行 SCRIPT KILL 或者 SHUTDOWN NOSAVE aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE); } if (server.lua_timedout) // 在脚本上下文中,启动文件事件处理(等待 SCRIPT KILL 或 SHUTDOWN NOSAVE) aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT); if (server.lua_kill) { // 杀死脚本 redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL."); lua_pushstring(lua,"Script killed by user with SCRIPT KILL..."); lua_error(lua); } }
void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { kitsune_update("main_loop"); /**DSU updatepoint */ if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
// 事件处理的主循环 void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { // 如果有需要在处理事件之前执行的函数,那么运行它 if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); // 开始处理事件 aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
void purgeCommand(redisClient *c) { uint32 check_purge_usleep = 10000; // 10ms while (!checkPurge()) { redisLog(REDIS_WARNING, "Check PURGE on SLAVE failed, sleeping: %dus", check_purge_usleep); usleep(check_purge_usleep); } addReply(c, shared.ok); aeProcessEvents(server.el, AE_ALL_EVENTS); if (prepareForShutdown() == REDIS_OK) exit(0); }
/* ae事件执行主程序 */ void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; //如果eventLoop中的stop标志位不为1,就循环处理 while (!eventLoop->stop) { //每次eventLoop事件执行完后又重新开始执行时调用 if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); //while循环处理所有的evetLoop的事件 aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
/*** * 事件处理循环主函数, 它循环地调用aeProcessEvents来处理事件, 直到退出事件循环 * @eventLoop[IN]: 时间循环处理器 */ void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { /* 如果设置的事件处理函数执行前的挂钩函数, 则先调用该函数 */ if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); /* 调用一次事件处理(处理所有类型事件) */ aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
//io主函数 void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { //在事件循环之前的一个回调,估计是用来初始,修改或重置eventLoop相关属性。 if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); //事件循环. aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
/* * 事件处理器主循环 * * eventLoop 事件处理器指针 * */ void aeMain(aeEventLoop *eventLoop) { // 设置事件处理器为启动状态 eventLoop->stop = 0; // 遍历事件处理器 while (!eventLoop->stop) { // 事件处理前的sleep方法不为空 if (eventLoop->beforesleep != NULL) // 执行sleep方法 eventLoop->beforesleep(eventLoop); // 调用对应复用库中的aeProcessEvents方法 aeProcessEvents(eventLoop, AE_ALL_EVENTS); } }
int main(int argc, char **argv) { config.daemonize = 0; config.logserver = "minard"; config.dataserver = "192.168.80.100";//"192.168.80.1"; config.logfile = ""; config.loglevel = NOTICE; parseOptions(argc, argv); strcpy(logfile, config.logfile); verbosity = config.loglevel; if (config.daemonize) daemonize(); signal(SIGPIPE, SIG_IGN); signal(SIGINT, sigint_handler); Log(NOTICE, "tubii server started"); el = aeCreateEventLoop(100); if ((aeCreateTimeEvent(el, 0, printSkipped, NULL, NULL)) == AE_ERR) { LogRaw(WARNING, "failed to set up printSkipped()"); } startLogServer(config.logserver, "tubii"); initServer(el, 4001, commandTable, sizeof(commandTable)/sizeof(struct command)); /* set up the dispatch_connect event which will try to connect to the * data stream server. If it can't connect, it will retry every 10 * seconds. */ if (data_connect(config.dataserver)) { Log(WARNING, "failed to set up data stream"); return 1; } auto_init(); /* start tubii readout */ if (start_tubii_readout(1000)) { //Log(WARNING, tubii_err); return 1; } /* set up status event */ if (aeCreateTimeEvent(el, 0, tubii_status, NULL, NULL) == AE_ERR) { Log(WARNING, "failed to set up status tubii"); return 1; } /* enter the main event loop */ el->stop = 0; while (!el->stop) { if (el->beforesleep != NULL) el->beforesleep(el); aeProcessEvents(el, AE_ALL_EVENTS); } Log(NOTICE, "ctrl-c caught. flushing buffers..."); time_t now = time(NULL); while (time(NULL) < now + 1) { if (aeProcessEvents(el, AE_FILE_EVENTS | AE_DONT_WAIT) == 0) break; } aeDeleteEventLoop(el); return 0; }
/* Replay the append log file. On error REDIS_OK is returned. On non fatal * error (the append only file is zero-length) REDIS_ERR is returned. On * fatal error an error message is logged and the program exists. */ int loadAppendOnlyFile(char *filename) { struct redisClient *fakeClient; FILE *fp = fopen(filename,"r"); struct redis_stat sb; int old_aof_state = server.aof_state; long loops = 0; if (fp && redis_fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) { server.aof_current_size = 0; fclose(fp); return REDIS_ERR; } if (fp == NULL) { redisLog(REDIS_WARNING,"Fatal error: can't open the append log file for reading: %s",strerror(errno)); exit(1); } /* Temporarily disable AOF, to prevent EXEC from feeding a MULTI * to the same file we're about to read. */ server.aof_state = REDIS_AOF_OFF; fakeClient = createFakeClient(); startLoading(fp); while(1) { int argc, j; unsigned long len; robj **argv; char buf[128]; sds argsds; struct redisCommand *cmd; /* Serve the clients from time to time */ if (!(loops++ % 1000)) { loadingProgress(ftello(fp)); aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT); } if (fgets(buf,sizeof(buf),fp) == NULL) { if (feof(fp)) break; else goto readerr; } if (buf[0] != '*') goto fmterr; argc = atoi(buf+1); if (argc < 1) goto fmterr; argv = zmalloc(sizeof(robj*)*argc); for (j = 0; j < argc; j++) { if (fgets(buf,sizeof(buf),fp) == NULL) goto readerr; if (buf[0] != '$') goto fmterr; len = strtol(buf+1,NULL,10); argsds = sdsnewlen(NULL,len); if (len && fread(argsds,len,1,fp) == 0) goto fmterr; argv[j] = createObject(REDIS_STRING,argsds); if (fread(buf,2,1,fp) == 0) goto fmterr; /* discard CRLF */ } /* Command lookup */ cmd = lookupCommand(argv[0]->ptr); if (!cmd) { redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", argv[0]->ptr); exit(1); } /* Run the command in the context of a fake client */ fakeClient->argc = argc; fakeClient->argv = argv; cmd->proc(fakeClient); /* The fake client should not have a reply */ redisAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0); /* The fake client should never get blocked */ redisAssert((fakeClient->flags & REDIS_BLOCKED) == 0); /* Clean up. Command code may have changed argv/argc so we use the * argv/argc of the client instead of the local variables. */ for (j = 0; j < fakeClient->argc; j++) decrRefCount(fakeClient->argv[j]); zfree(fakeClient->argv); } /* This point can only be reached when EOF is reached without errors. * If the client is in the middle of a MULTI/EXEC, log error and quit. */ if (fakeClient->flags & REDIS_MULTI) goto readerr; fclose(fp); freeFakeClient(fakeClient); server.aof_state = old_aof_state; stopLoading(); aofUpdateCurrentSize(); server.aof_rewrite_base_size = server.aof_current_size; return REDIS_OK; readerr: if (feof(fp)) { redisLog(REDIS_WARNING,"Unexpected end of file reading the append only file"); } else { redisLog(REDIS_WARNING,"Unrecoverable error reading the append only file: %s", strerror(errno)); } exit(1); fmterr: redisLog(REDIS_WARNING,"Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>"); exit(1); }