aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llerrorstream.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llerrorstream.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llerrorstream.cpp')
-rw-r--r--linden/indra/llcommon/llerrorstream.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llerrorstream.cpp b/linden/indra/llcommon/llerrorstream.cpp
new file mode 100644
index 0000000..ed54d88
--- /dev/null
+++ b/linden/indra/llcommon/llerrorstream.cpp
@@ -0,0 +1,188 @@
1/**
2 * @file llerrorstream.cpp
3 * @brief Implementation of c++ log straming.
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llerrorstream.h"
31#include "llerrorbuffer.h"
32#include "llerror.h"
33
34using namespace std;
35
36// Define this if we're using APR mutexes.
37#include "llapr.h"
38extern apr_thread_mutex_t *gLogMutexp;
39
40// In order to compile in Visual C++ 6.0, you must use std:: in the header, and then
41// use the std namespace in the cpp. Otherwise, you'll break the (very) fragile C++ parser.
42LLErrorStream::LLErrorStream(LLErrorBuffer *eb):
43 ostream(eb),
44 mErrorBuffer(eb),
45 mKill(FALSE),
46 mErrorCallback(NULL)
47{
48#ifdef SHOW_DEBUG
49 setErrorLevel(LLErrorBuffer::DEBUG);
50#else
51#ifdef SHOW_INFO
52 setErrorLevel(LLErrorBuffer::INFO);
53#else
54#ifdef SHOW_WARN
55 setErrorLevel(LLErrorBuffer::WARN);
56#else
57 setErrorLevel(LLErrorBuffer::FATAL);
58#endif // SHOW_WARN
59#endif // SHOW_INFO
60#endif // SHOW_DEBUG
61
62 setDebugMask(LLERR_NONE);
63 setPrintLocation(FALSE);
64}
65
66LLErrorBuffer::ELevel LLErrorStream::ELevelToBufferELevel(const ELevel l)
67{
68 switch (l)
69 {
70 case DEBUG:
71 return LLErrorBuffer::DEBUG;
72 case INFO:
73 return LLErrorBuffer::INFO;
74 case WARN:
75 return LLErrorBuffer::WARN;
76 case FATAL:
77 return LLErrorBuffer::FATAL;
78 default:
79 return LLErrorBuffer::FATAL;
80 }
81}
82
83LLErrorStream::ELevel LLErrorStream::BufferELevelToELevel(const LLErrorBuffer::ELevel l)
84{
85 switch(l)
86 {
87 case LLErrorBuffer::DEBUG:
88 return DEBUG;
89 case LLErrorBuffer::INFO:
90 return INFO;
91 case LLErrorBuffer::WARN:
92 return WARN;
93 case LLErrorBuffer::FATAL:
94 return FATAL;
95 default:
96 return FATAL;
97 }
98}
99
100
101BOOL LLErrorStream::isEnabledFor(const LLErrorBuffer::ELevel l)
102{
103 if (l == LLErrorBuffer::FATAL)
104 {
105 if (LLErrorBuffer::FATAL < getErrorLevel())
106 {
107 // Fatal error, but we're at log level NONE (used by signal handlers)
108 // We want to crash this process now instead of logging
109 _llcrash_and_loop();
110 }
111 }
112 // Always returns false if not safe (recursive call)
113 return (getErrorLevel() <= l);
114}
115
116
117BOOL LLErrorStream::isEnabledFor(const LLErrorBuffer::ELevel l, const U32 type)
118{
119 // Always returns false if not safe (recursive call)
120 return (getErrorLevel() <= l) && (mDebugMask & type);
121}
122
123
124
125void LLErrorStream::crashOnError(std::ostringstream &oss, LLErrorBuffer::ELevel l)
126{
127 if (gLogMutexp)
128 {
129 const S32 MAX_RETRIES = 5;
130 S32 attempts = 0;
131 while (attempts < MAX_RETRIES)
132 {
133 apr_status_t s = apr_thread_mutex_trylock(gLogMutexp);
134 if (!APR_STATUS_IS_EBUSY(s))
135 {
136 break;
137 }
138 else
139 {
140 attempts++;
141 ms_sleep(1);
142
143 //
144 // Just yielding won't necessarily work, I had problems with this on Linux - doug 12/02/04
145 //apr_thread_yield();
146 }
147 }
148 if (attempts == MAX_RETRIES)
149 {
150 // We're hosed, we can't get the mutex.
151 // I guess we just won't log, then. Blah.
152 fprintf(stderr, "LLErrorStream::crashOnError() failed to get mutex for log\n");
153 return;
154 }
155 }
156
157 mErrorBuffer->setPriority(l);
158 if (LLErrorBuffer::FATAL == l)
159 {
160 setError();
161 }
162
163 *this << oss.str();
164
165 if (mKill)
166 {
167 // We want to flush this stream.
168 flush();
169 }
170
171 BOOL crashme = FALSE;
172 if (mKill)
173 {
174 crashme = TRUE;
175 }
176 mKill = FALSE;
177
178 if (gLogMutexp)
179 {
180 apr_thread_mutex_unlock(gLogMutexp);
181 }
182
183 if (crashme)
184 {
185 mErrorCallback(oss.str());
186 _llcrash_and_loop();
187 }
188}