aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llerror.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llerror.cpp')
-rw-r--r--linden/indra/llcommon/llerror.cpp191
1 files changed, 190 insertions, 1 deletions
diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp
index cf4b341..30b61a9 100644
--- a/linden/indra/llcommon/llerror.cpp
+++ b/linden/indra/llcommon/llerror.cpp
@@ -18,7 +18,8 @@
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 21 * online at
22 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 23 *
23 * By copying, modifying or distributing this software, you acknowledge 24 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 25 * that you have read and understood your obligations described above,
@@ -987,6 +988,38 @@ namespace LLError
987 988
988 return new std::ostringstream; 989 return new std::ostringstream;
989 } 990 }
991
992 void Log::flush(std::ostringstream* out, char* message)
993 {
994 LogLock lock;
995 if (!lock.ok())
996 {
997 return;
998 }
999
1000 if(strlen(out->str().c_str()) < 128)
1001 {
1002 strcpy(message, out->str().c_str());
1003 }
1004 else
1005 {
1006 strncpy(message, out->str().c_str(), 127);
1007 message[127] = '\0' ;
1008 }
1009
1010 Globals& g = Globals::get();
1011 if (out == &g.messageStream)
1012 {
1013 g.messageStream.clear();
1014 g.messageStream.str("");
1015 g.messageStreamInUse = false;
1016 }
1017 else
1018 {
1019 delete out;
1020 }
1021 return ;
1022 }
990 1023
991 void Log::flush(std::ostringstream* out, const CallSite& site) 1024 void Log::flush(std::ostringstream* out, const CallSite& site)
992 { 1025 {
@@ -1202,3 +1235,159 @@ namespace LLError
1202 } 1235 }
1203} 1236}
1204 1237
1238namespace LLError
1239{
1240 char** LLCallStacks::sBuffer = NULL ;
1241 S32 LLCallStacks::sIndex = 0 ;
1242
1243 class CallStacksLogLock
1244 {
1245 public:
1246 CallStacksLogLock();
1247 ~CallStacksLogLock();
1248 bool ok() const { return mOK; }
1249 private:
1250 bool mLocked;
1251 bool mOK;
1252 };
1253
1254 CallStacksLogLock::CallStacksLogLock()
1255 : mLocked(false), mOK(false)
1256 {
1257 if (!gCallStacksLogMutexp)
1258 {
1259 mOK = true;
1260 return;
1261 }
1262
1263 const int MAX_RETRIES = 5;
1264 for (int attempts = 0; attempts < MAX_RETRIES; ++attempts)
1265 {
1266 apr_status_t s = apr_thread_mutex_trylock(gCallStacksLogMutexp);
1267 if (!APR_STATUS_IS_EBUSY(s))
1268 {
1269 mLocked = true;
1270 mOK = true;
1271 return;
1272 }
1273
1274 ms_sleep(1);
1275 }
1276
1277 // We're hosed, we can't get the mutex. Blah.
1278 std::cerr << "CallStacksLogLock::CallStacksLogLock: failed to get mutex for log"
1279 << std::endl;
1280 }
1281
1282 CallStacksLogLock::~CallStacksLogLock()
1283 {
1284 if (mLocked)
1285 {
1286 apr_thread_mutex_unlock(gCallStacksLogMutexp);
1287 }
1288 }
1289
1290 //static
1291 void LLCallStacks::push(const char* function, const int line)
1292 {
1293 CallStacksLogLock lock;
1294 if (!lock.ok())
1295 {
1296 return;
1297 }
1298
1299 if(!sBuffer)
1300 {
1301 sBuffer = new char*[512] ;
1302 sBuffer[0] = new char[512 * 128] ;
1303 for(S32 i = 1 ; i < 512 ; i++)
1304 {
1305 sBuffer[i] = sBuffer[i-1] + 128 ;
1306 }
1307 sIndex = 0 ;
1308 }
1309
1310 if(sIndex > 511)
1311 {
1312 clear() ;
1313 }
1314
1315 strcpy(sBuffer[sIndex], function) ;
1316 sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
1317 sIndex++ ;
1318
1319 return ;
1320 }
1321
1322 //static
1323 std::ostringstream* LLCallStacks::insert(const char* function, const int line)
1324 {
1325 std::ostringstream* _out = LLError::Log::out();
1326 *_out << function << " line " << line << " " ;
1327
1328 return _out ;
1329 }
1330
1331 //static
1332 void LLCallStacks::end(std::ostringstream* _out)
1333 {
1334 CallStacksLogLock lock;
1335 if (!lock.ok())
1336 {
1337 return;
1338 }
1339
1340 if(!sBuffer)
1341 {
1342 sBuffer = new char*[512] ;
1343 sBuffer[0] = new char[512 * 128] ;
1344 for(S32 i = 1 ; i < 512 ; i++)
1345 {
1346 sBuffer[i] = sBuffer[i-1] + 128 ;
1347 }
1348 sIndex = 0 ;
1349 }
1350
1351 if(sIndex > 511)
1352 {
1353 clear() ;
1354 }
1355
1356 LLError::Log::flush(_out, sBuffer[sIndex++]) ;
1357 }
1358
1359 //static
1360 void LLCallStacks::print()
1361 {
1362 CallStacksLogLock lock;
1363 if (!lock.ok())
1364 {
1365 return;
1366 }
1367
1368 if(sIndex > 0)
1369 {
1370 llinfos << " ************* PRINT OUT LL CALL STACKS ************* " << llendl ;
1371 while(sIndex > 0)
1372 {
1373 sIndex-- ;
1374 llinfos << sBuffer[sIndex] << llendl ;
1375 }
1376 llinfos << " *************** END OF LL CALL STACKS *************** " << llendl ;
1377 }
1378
1379 if(sBuffer)
1380 {
1381 delete[] sBuffer[0] ;
1382 delete[] sBuffer ;
1383 sBuffer = NULL ;
1384 }
1385 }
1386
1387 //static
1388 void LLCallStacks::clear()
1389 {
1390 sIndex = 0 ;
1391 }
1392}
1393