summaryrefslogtreecommitdiff
path: root/indra/llcrashlogger/llcrashlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcrashlogger/llcrashlock.cpp')
-rw-r--r--indra/llcrashlogger/llcrashlock.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp
new file mode 100644
index 0000000000..c3d2f944fc
--- /dev/null
+++ b/indra/llcrashlogger/llcrashlock.cpp
@@ -0,0 +1,209 @@
+/**
+ * @file llformat.cpp
+ * @date January 2007
+ * @brief string formatting utility
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llcrashlock.h"
+#include "lldir.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llnametable.h"
+#include "llframetimer.h"
+#include <boost/filesystem.hpp>
+#include <string>
+#include <iostream>
+#include <stdio.h>
+
+
+#if LL_WINDOWS //For windows platform.
+#include <windows.h>
+#include <TlHelp32.h>
+
+namespace {
+ inline DWORD getpid() {
+ return GetCurrentProcessId();
+ }
+}
+
+bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
+{
+ std::wstring wpname;
+ wpname = std::wstring(pname.begin(), pname.end());
+
+ HANDLE snapshot;
+ PROCESSENTRY32 pe32;
+
+ bool matched = false;
+
+ snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+ else
+ {
+ pe32.dwSize = sizeof(PROCESSENTRY32);
+ if (Process32First(snapshot, &pe32))
+ {
+ do {
+ std::wstring wexecname = pe32.szExeFile;
+ std::string execname = std::string(wexecname.begin(), wexecname.end());
+ if (!wpname.compare(pe32.szExeFile))
+ {
+ if (pid == (U32)pe32.th32ProcessID)
+ {
+ matched = true;
+ break;
+ }
+ }
+ } while (Process32Next(snapshot, &pe32));
+ }
+ }
+
+ CloseHandle(snapshot);
+ return matched;
+}
+
+#else //Everyone Else
+bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
+{
+ //Will boost.process ever become a reality?
+ std::stringstream cmd;
+
+ cmd << "pgrep '" << pname << "' | grep '^" << pid << "$'";
+ return (!system(cmd.str().c_str()));
+}
+#endif //Everyone else.
+
+
+LLCrashLock::LLCrashLock() : mCleanUp(true), mWaitingPID(0)
+{
+}
+
+void LLCrashLock::setCleanUp(bool cleanup)
+{
+ mCleanUp = cleanup; //Allow cleanup to be disabled for debugging.
+}
+
+LLSD LLCrashLock::getLockFile(std::string filename)
+{
+ LLSD lock_sd = LLSD::emptyMap();
+
+ llifstream ifile(filename);
+
+ if (ifile.is_open())
+ {
+ LLSDSerialize::fromXML(lock_sd, ifile);
+ ifile.close();
+ }
+
+ return lock_sd;
+}
+
+bool LLCrashLock::putLockFile(std::string filename, const LLSD& data)
+{
+ bool result = true;
+ llofstream ofile(filename);
+
+ if (!LLSDSerialize::toXML(data,ofile))
+ {
+ result=false;
+ }
+ ofile.close();
+ return result;
+}
+
+bool LLCrashLock::requestMaster( F32 timeout )
+{
+ if (mMaster.empty())
+ {
+ mMaster = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "crash_master.lock");
+ }
+
+ LLSD lock_sd=getLockFile(mMaster);
+
+ if (lock_sd.has("pid"))
+ {
+ mWaitingPID = lock_sd["pid"].asInteger();
+ if ( isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()) )
+ {
+ mTimer.resetWithExpiry(timeout);
+ return false;
+ }
+ }
+
+ U32 pid = getpid();
+ lock_sd["pid"] = (LLSD::Integer)pid;
+ return putLockFile(mMaster,lock_sd);
+}
+
+bool LLCrashLock::checkMaster()
+{
+ if (mWaitingPID)
+ {
+ return (!isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()));
+ }
+ return false;
+}
+
+bool LLCrashLock::isWaiting()
+{
+ return !mTimer.hasExpired();
+}
+
+void LLCrashLock::releaseMaster()
+{
+ //Yeeeeeeehaw
+ unlink(mMaster.c_str());
+}
+
+LLSD LLCrashLock::getProcessList()
+{
+ if (mDumpTable.empty())
+ {
+ mDumpTable= gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "crash_table.lock");
+ }
+ return getLockFile(mDumpTable);
+}
+
+//static
+bool LLCrashLock::fileExists(std::string filename)
+{
+ return boost::filesystem::exists(filename.c_str());
+}
+
+void LLCrashLock::cleanupProcess(std::string proc_dir)
+{
+ boost::filesystem::remove_all(proc_dir);
+}
+
+bool LLCrashLock::putProcessList(const LLSD& proc_sd)
+{
+ return putLockFile(mDumpTable,proc_sd);
+}