--- deliantra/server/common/logger.C 2009/10/12 14:00:57 1.20 +++ deliantra/server/common/logger.C 2012/01/03 11:25:31 1.28 @@ -1,9 +1,7 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team - * Copyright (©) 1992,2007 Frank Tore Johansen + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the @@ -42,37 +40,45 @@ int flags; }; +typedef std::vector > logvector; + static SMUTEX(mutex); +static SMUTEX(fdlock); static SCOND(cond); static int logfd = STDERR_FILENO; static int logsync = 1; -static std::vector > queue; +static logvector queue; -void set_logfd (int fd) +int log_setfd (int fd) { - SMUTEX_LOCK (mutex); + SMUTEX_LOCK (fdlock); + int old = logfd; logfd = fd < 0 ? STDERR_FILENO : fd; - SMUTEX_UNLOCK (mutex); + SMUTEX_UNLOCK (fdlock); + + return old; } -#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000+") - 1 +#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000 L+") - 1 static void log_sync (logline &line) { + static const char levelchar [16+1] = "EWIDt???????????"; struct tm lt; char pfx [PREFIX_LEN]; localtime_r (&line.tv.tv_sec, <); - sprintf (pfx, "%04d-%02d-%02d %02d:%02d:%02d.%04d", + sprintf (pfx, "%04d-%02d-%02d %02d:%02d:%02d.%04d %c", lt.tm_year + 1900, lt.tm_mon + 1, lt.tm_mday, lt.tm_hour, lt.tm_min, lt.tm_sec, - (int)(line.tv.tv_usec / 100) + (int)(line.tv.tv_usec / 100), + levelchar [line.flags & 15] ); pfx [PREFIX_LEN - 1] = line.flags & logSync ? '=' : ' '; @@ -84,6 +90,9 @@ char *buf = line.buf; + if (logsync != 2) + SMUTEX_LOCK (fdlock); + while (char *end = strchr (buf, '\n')) { iov [1].iov_base = buf; @@ -101,6 +110,9 @@ pfx [PREFIX_LEN - 1] = '+'; } + if (logsync != 2) + SMUTEX_UNLOCK (fdlock); + sfree (line.buf, line.len); } @@ -125,7 +137,11 @@ // we have bigger problems. if (idx == queue.size ()) { - queue.clear (); + if (idx < 32) + queue.clear (); + else + logvector ().swap (queue); // free memory, hopefully + idx = 0; } @@ -139,6 +155,7 @@ log_cleanup () { logsync = 1; + SMUTEX_UNLOCK (fdlock); for (;;) { @@ -152,13 +169,15 @@ break; usleep (10000); + SMUTEX_LOCK (fdlock); + SMUTEX_UNLOCK (fdlock); } } static void af_child () { - logsync = 1; + logsync = 2; } static struct logthread : thread @@ -172,7 +191,7 @@ } logthread; void -LOG (int flags, const char *format, ...) +LOG (int flags, const_utf8_string format, ...) { int level = flags & 15; @@ -224,3 +243,25 @@ } } +static int suspended; + +void +log_suspend () +{ + if (!suspended++) + { + LOG (llevDebug, "logging suspended."); + SMUTEX_LOCK (fdlock); + } +} + +void +log_resume () +{ + if (!--suspended) + { + SMUTEX_UNLOCK (fdlock); + LOG (llevDebug, "logging resumed."); + } +} +