ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/logger.C
(Generate patch)

Comparing deliantra/server/common/logger.C (file contents):
Revision 1.18 by root, Wed Apr 30 06:40:28 2008 UTC vs.
Revision 1.25 by root, Sun Apr 11 17:54:13 2010 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 5 *
8 * Deliantra is free software: you can redistribute it and/or modify 6 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 7 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 8 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 9 * option) any later version.
12 * 10 *
13 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 14 * GNU General Public License for more details.
17 * 15 *
18 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * and the GNU General Public License along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
20 * 19 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 20 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 21 */
23 22
24#include <cstdarg> 23#include <cstdarg>
39 char *buf; // includes PREFIX_LEN garbage bytes 38 char *buf; // includes PREFIX_LEN garbage bytes
40 int len; 39 int len;
41 int flags; 40 int flags;
42}; 41};
43 42
43typedef std::vector<logline, slice_allocator<logline> > logvector;
44
44static SMUTEX(mutex); 45static SMUTEX(mutex);
46static SMUTEX(fdlock);
45static SCOND(cond); 47static SCOND(cond);
46static int logfd = STDERR_FILENO; 48static int logfd = STDERR_FILENO;
47static int logsync = 1; 49static int logsync = 1;
48static std::vector<logline, slice_allocator<logline> > queue; 50static logvector queue;
49 51
50void set_logfd (int fd) 52int log_setfd (int fd)
51{ 53{
52 SMUTEX_LOCK (mutex); 54 SMUTEX_LOCK (fdlock);
55 int old = logfd;
53 logfd = fd < 0 ? STDERR_FILENO : fd; 56 logfd = fd < 0 ? STDERR_FILENO : fd;
54 SMUTEX_UNLOCK (mutex); 57 SMUTEX_UNLOCK (fdlock);
58
59 return old;
55} 60}
56 61
57#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000+") - 1 62#define PREFIX_LEN sizeof ("0000-00-00 00:00:00.0000+") - 1
58 63
59static void 64static void
81 iov [0].iov_base = pfx; 86 iov [0].iov_base = pfx;
82 iov [0].iov_len = PREFIX_LEN; 87 iov [0].iov_len = PREFIX_LEN;
83 88
84 char *buf = line.buf; 89 char *buf = line.buf;
85 90
91 if (logsync != 2)
92 SMUTEX_LOCK (fdlock);
93
86 while (char *end = strchr (buf, '\n')) 94 while (char *end = strchr (buf, '\n'))
87 { 95 {
88 iov [1].iov_base = buf; 96 iov [1].iov_base = buf;
89 iov [1].iov_len = end - buf + 1; 97 iov [1].iov_len = end - buf + 1;
90 98
97 if (buf == line.buf + line.len) 105 if (buf == line.buf + line.len)
98 break; 106 break;
99 107
100 pfx [PREFIX_LEN - 1] = '+'; 108 pfx [PREFIX_LEN - 1] = '+';
101 } 109 }
110
111 if (logsync != 2)
112 SMUTEX_UNLOCK (fdlock);
102 113
103 sfree (line.buf, line.len); 114 sfree (line.buf, line.len);
104} 115}
105 116
106static void * 117static void *
122 // this algorithm could result in an ever-increasing vector 133 // this algorithm could result in an ever-increasing vector
123 // size if we log faster than we can write, but if that happens 134 // size if we log faster than we can write, but if that happens
124 // we have bigger problems. 135 // we have bigger problems.
125 if (idx == queue.size ()) 136 if (idx == queue.size ())
126 { 137 {
138 if (idx < 32)
127 queue.clear (); 139 queue.clear ();
140 else
141 logvector ().swap (queue); // free memory, hopefully
142
128 idx = 0; 143 idx = 0;
129 } 144 }
130 145
131 SMUTEX_UNLOCK (mutex); 146 SMUTEX_UNLOCK (mutex);
132 147
136 151
137void 152void
138log_cleanup () 153log_cleanup ()
139{ 154{
140 logsync = 1; 155 logsync = 1;
156 SMUTEX_UNLOCK (fdlock);
141 157
142 for (;;) 158 for (;;)
143 { 159 {
144 int done; 160 int done;
145 161
149 165
150 if (done) 166 if (done)
151 break; 167 break;
152 168
153 usleep (10000); 169 usleep (10000);
170 SMUTEX_LOCK (fdlock);
171 SMUTEX_UNLOCK (fdlock);
154 } 172 }
155} 173}
156 174
157static void 175static void
158af_child () 176af_child ()
159{ 177{
160 logsync = 1; 178 logsync = 2;
161} 179}
162 180
163static struct logthread : thread 181static struct logthread : thread
164{ 182{
165 logthread () 183 logthread ()
169 logsync = 0; 187 logsync = 0;
170 } 188 }
171} logthread; 189} logthread;
172 190
173void 191void
174LOG (int flags, const char *format, ...) 192LOG (int flags, const_utf8_string format, ...)
175{ 193{
176 int level = flags & 15; 194 int level = flags & 15;
177 195
178 if (level > settings.debug) 196 if (level > settings.debug)
179 return; 197 return;
221 SMUTEX_UNLOCK (mutex); 239 SMUTEX_UNLOCK (mutex);
222 SCOND_SIGNAL (cond); 240 SCOND_SIGNAL (cond);
223 } 241 }
224} 242}
225 243
244static int suspended;
245
246void
247log_suspend ()
248{
249 if (!suspended++)
250 {
251 LOG (llevDebug, "logging suspended.");
252 SMUTEX_LOCK (fdlock);
253 }
254}
255
256void
257log_resume ()
258{
259 if (!--suspended)
260 {
261 SMUTEX_UNLOCK (fdlock);
262 LOG (llevDebug, "logging resumed.");
263 }
264}
265

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines