diff options
-rw-r--r-- | include/llvm/Support/Process.h | 63 | ||||
-rw-r--r-- | lib/Support/Process.cpp | 22 | ||||
-rw-r--r-- | lib/Support/Unix/Process.inc | 6 | ||||
-rw-r--r-- | lib/Support/Windows/Process.inc | 6 | ||||
-rw-r--r-- | unittests/Support/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Support/ProcessTest.cpp | 33 |
6 files changed, 130 insertions, 1 deletions
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 2113f62..080634c 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -25,11 +25,74 @@ #ifndef LLVM_SYSTEM_PROCESS_H #define LLVM_SYSTEM_PROCESS_H +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/TimeValue.h" namespace llvm { namespace sys { +class self_process; + +/// \brief Generic base class which exposes information about an operating +/// system process. +/// +/// This base class is the core interface behind any OS process. It exposes +/// methods to query for generic information about a particular process. +/// +/// Subclasses implement this interface based on the mechanisms available, and +/// can optionally expose more interfaces unique to certain process kinds. +class process { +protected: + /// \brief Only specific subclasses of process objects can be destroyed. + virtual ~process(); + +public: + /// \brief Operating system specific type to identify a process. + /// + /// Note that the windows one is defined to 'void *' as this is the + /// documented type for HANDLE on windows, and we don't want to pull in the + /// Windows headers here. +#if defined(LLVM_ON_UNIX) + typedef pid_t id_type; +#elif defined(LLVM_ON_WIN32) + typedef void *id_type; // Must match the type of HANDLE. +#else +#error Unsupported operating system. +#endif + + /// \brief Get the operating system specific identifier for this process. + virtual id_type get_id() = 0; + + + /// \name Static factory routines for processes. + /// @{ + + /// \brief Get the process object for the current process. + static self_process *get_self(); + + /// @} + +}; + +/// \brief The specific class representing the current process. +/// +/// The current process can both specialize the implementation of the routines +/// and can expose certain information not available for other OS processes. +class self_process : public process { + friend class process; + + /// \brief Private destructor, as users shouldn't create objects of this + /// type. + virtual ~self_process(); + +public: + virtual id_type get_id(); + +private: +}; + + /// \brief A collection of legacy interfaces for querying information about the /// current executing process. class Process { diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp index 88ca7c3..8d1b648 100644 --- a/lib/Support/Process.cpp +++ b/lib/Support/Process.cpp @@ -11,8 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/Process.h" #include "llvm/Config/config.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/ErrorHandling.h" namespace llvm { using namespace sys; @@ -22,6 +23,25 @@ using namespace sys; //=== independent code. //===----------------------------------------------------------------------===// +// Empty virtual destructor to anchor the vtable for the process class. +process::~process() {} + +self_process *process::get_self() { + // Use a function local static for thread safe initialization and allocate it + // as a raw pointer to ensure it is never destroyed. + static self_process *SP = new self_process(); + + return SP; +} + +// The destructor for the self_process subclass must never actually be +// executed. There should be at most one instance of this class, and that +// instance should live until the process terminates to avoid the potential for +// racy accesses during shutdown. +self_process::~self_process() { + llvm_unreachable("This destructor must never be executed!"); +} + } // Include the platform-specific parts of this class. diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc index 5204147..dedc443 100644 --- a/lib/Support/Unix/Process.inc +++ b/lib/Support/Unix/Process.inc @@ -44,6 +44,12 @@ using namespace llvm; using namespace sys; + +process::id_type self_process::get_id() { + return getpid(); +} + + unsigned Process::GetPageSize() { diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc index 89dbf23..fc24cea 100644 --- a/lib/Support/Windows/Process.inc +++ b/lib/Support/Windows/Process.inc @@ -38,6 +38,12 @@ namespace llvm { using namespace sys; + +process::id_type self_process::get_id() { + return GetCurrentProcess(); +} + + // This function retrieves the page size using GetSystemInfo and is present // solely so it can be called once in Process::GetPageSize to initialize the // static variable PageSize. diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt index f6a5949..c9a330d 100644 --- a/unittests/Support/CMakeLists.txt +++ b/unittests/Support/CMakeLists.txt @@ -20,6 +20,7 @@ add_llvm_unittest(SupportTests MemoryBufferTest.cpp MemoryTest.cpp Path.cpp + ProcessTest.cpp RegexTest.cpp SwapByteOrderTest.cpp TimeValue.cpp diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp new file mode 100644 index 0000000..d4c4b54 --- /dev/null +++ b/unittests/Support/ProcessTest.cpp @@ -0,0 +1,33 @@ +//===- unittest/Support/ProcessTest.cpp -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Process.h" +#include "gtest/gtest.h" + +#ifdef LLVM_ON_WIN32 +#include "windows.h" +#endif + +namespace { + +using namespace llvm; +using namespace sys; + +TEST(ProcessTest, SelfProcess) { + EXPECT_TRUE(process::get_self()); + EXPECT_EQ(process::get_self(), process::get_self()); + +#if defined(LLVM_ON_UNIX) + EXPECT_EQ(getpid(), process::get_self()->get_id()); +#elif defined(LLVM_ON_WIN32) + EXPECT_EQ(GetCurrentProcess(), process::get_self()->get_id()); +#endif +} + +} // end anonymous namespace |