diff options
Diffstat (limited to 'linden/indra/llcommon/llerror.cpp')
-rw-r--r-- | linden/indra/llcommon/llerror.cpp | 191 |
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 | ||
1238 | namespace 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 | |||