redisLogRaw(level,msg);
}
+/* Log a fixed message without printf-alike capabilities, in a way that is
+ * safe to call from a signal handler.
+ *
+ * We actually use this only for signals that are not fatal from the point
+ * of view of Redis. Signals that are going to kill the server anyway and
+ * where we need printf-alike features are served by redisLog(). */
+void redisLogFromHandler(int level, const char *msg) {
+ int fd;
+ char buf[64];
+
+ if ((level&0xff) < server.verbosity ||
+ (server.logfile == NULL && server.daemonize)) return;
+ fd = server.logfile ?
+ open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644) :
+ STDOUT_FILENO;
+ if (fd == -1) return;
+ ll2string(buf,sizeof(buf),getpid());
+ write(fd,"[",1);
+ write(fd,buf,strlen(buf));
+ write(fd," | signal handler] (",20);
+ ll2string(buf,sizeof(buf),time(NULL));
+ write(fd,buf,strlen(buf));
+ write(fd,") ",2);
+ write(fd,msg,strlen(msg));
+ write(fd,"\n",1);
+ if (server.logfile) close(fd);
+}
+
/* Redis generally does not try to recover from out of memory conditions
* when allocating objects or strings, it is not clear if it will be possible
* to report this condition to the client since the networking layer itself
REDIS_NOTUSED(id);
REDIS_NOTUSED(clientData);
+ /* Software watchdog: deliver the SIGALRM that will reach the signal
+ * handler if we don't return here fast enough. */
+ if (server.watchdog_period) watchdogScheduleSignal(server.watchdog_period);
+
/* We take a cached value of the unix time in the global state because
* with virtual memory and aging there is to store the current time
* in objects at every object access, and accuracy is not needed.
shared.space = createObject(REDIS_STRING,sdsnew(" "));
shared.colon = createObject(REDIS_STRING,sdsnew(":"));
shared.plus = createObject(REDIS_STRING,sdsnew("+"));
- shared.select0 = createStringObject("select 0\r\n",10);
- shared.select1 = createStringObject("select 1\r\n",10);
- shared.select2 = createStringObject("select 2\r\n",10);
- shared.select3 = createStringObject("select 3\r\n",10);
- shared.select4 = createStringObject("select 4\r\n",10);
- shared.select5 = createStringObject("select 5\r\n",10);
- shared.select6 = createStringObject("select 6\r\n",10);
- shared.select7 = createStringObject("select 7\r\n",10);
- shared.select8 = createStringObject("select 8\r\n",10);
- shared.select9 = createStringObject("select 9\r\n",10);
+
+ for (j = 0; j < REDIS_SHARED_SELECT_CMDS; j++) {
+ shared.select[j] = createObject(REDIS_STRING,
+ sdscatprintf(sdsempty(),"select %d\r\n", j));
+ }
shared.messagebulk = createStringObject("$7\r\nmessage\r\n",13);
shared.pmessagebulk = createStringObject("$8\r\npmessage\r\n",14);
shared.subscribebulk = createStringObject("$9\r\nsubscribe\r\n",15);
server.slowlog_log_slower_than = REDIS_SLOWLOG_LOG_SLOWER_THAN;
server.slowlog_max_len = REDIS_SLOWLOG_MAX_LEN;
- /* Assert */
+ /* Debugging */
server.assert_failed = "<no assertion failed>";
server.assert_file = "<no file>";
server.assert_line = 0;
server.bug_report_start = 0;
+ server.watchdog_period = 0;
}
/* This function will try to raise the max number of open files accordingly to
static void sigtermHandler(int sig) {
REDIS_NOTUSED(sig);
- redisLog(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
+ redisLogFromHandler(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
server.shutdown_asap = 1;
}