summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Utility/CleanUp.h188
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj4
2 files changed, 192 insertions, 0 deletions
diff --git a/lldb/include/lldb/Utility/CleanUp.h b/lldb/include/lldb/Utility/CleanUp.h
new file mode 100644
index 00000000000..3bced8feeec
--- /dev/null
+++ b/lldb/include/lldb/Utility/CleanUp.h
@@ -0,0 +1,188 @@
+//===-- CleanUp.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CleanUp_h_
+#define liblldb_CleanUp_h_
+
+#include "lldb/lldb-include.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+// Templated class that guarantees that a cleanup callback function will
+// be called. The cleanup function will be called once under the
+// following conditions:
+// - when the object goes out of scope
+// - when the user explicitly calls clean.
+// - the current value will be cleaned up when a new value is set using
+// set(T value) as long as the current value hasn't already been cleaned.
+//
+// This class is designed to be used with simple types for type T (like
+// file descriptors, opaque handles, pointers, etc). If more complex
+// type T objects are desired, we need to probably specialize this class
+// to take "const T&" for all input T parameters. Yet if a type T is
+// complex already it might be better to build the cleanup funcionality
+// into T.
+//
+// The cleanup function must take one argument that is of type T.
+// The calback fucntion return type is R. The return value is currently
+// needed for "CallbackType". If there is an easy way to get around the
+// need for the return value we can change this class.
+//
+// The two template parameters are:
+// T - The variable type of value that will be stored and used as the
+// sole argument for the cleanup callback.
+// R - The return type for the cleanup function.
+//
+// EXAMPLES
+// // Use with file handles that get opened where you want to close
+// // them. Below we use "int open(const char *path, int oflag, ...)"
+// // which returns an integer file descriptor. -1 is the invalid file
+// // descriptor so to make an object that will call "int close(int fd)"
+// // automatically we can use:
+//
+// CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
+//
+// // malloc/free example
+// CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
+//----------------------------------------------------------------------
+template <typename T, typename R>
+class CleanUp
+{
+public:
+ typedef T value_type;
+ typedef R (*CallbackType)(value_type);
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value only. No values are
+ // considered to be invalid and the cleanup function will be called
+ // regardless of the value of m_current_value.
+ //----------------------------------------------------------------------
+ CleanUp (value_type value, CallbackType callback) :
+ m_current_value (value),
+ m_invalid_value (),
+ m_callback (callback),
+ m_callback_called (false),
+ m_invalid_value_is_valid (false)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Constructor that sets the current value and also the invalid value.
+ // The cleanup function will be called on "m_value" as long as it isn't
+ // equal to "m_invalid_value".
+ //----------------------------------------------------------------------
+ CleanUp (value_type value, value_type invalid, CallbackType callback) :
+ m_current_value (value),
+ m_callback (callback),
+ m_invalid_value (invalid),
+ m_callback_called (false),
+ m_invalid_value_is_valid (true)
+ {
+ }
+
+ //----------------------------------------------------------------------
+ // Automatically cleanup when this object goes out of scope.
+ //----------------------------------------------------------------------
+ ~CleanUp ()
+ {
+ clean();
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ value_type get()
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Access the value stored in this class
+ //----------------------------------------------------------------------
+ const value_type
+ get() const
+ {
+ return m_current_value;
+ }
+
+ //----------------------------------------------------------------------
+ // Reset the owned value to "value". If a current value is valid and
+ // the cleanup callback hasn't been called, the previous value will
+ // be cleaned up (see void CleanUp::clean()).
+ //----------------------------------------------------------------------
+ void
+ set (const value_type value)
+ {
+ // Cleanup the current value if needed
+ clean ();
+ // Now set the new value and mark our callback as not called
+ m_callback_called = false;
+ m_current_value = value;
+ }
+
+ //----------------------------------------------------------------------
+ // Checks is "m_current_value" is valid. The value is considered valid
+ // no invalid value was supplied during construction of this object or
+ // if an invalid value was supplied and "m_current_value" is not equal
+ // to "m_invalid_value".
+ //
+ // Returns true if "m_current_value" is valid, false otherwise.
+ //----------------------------------------------------------------------
+ bool
+ is_valid() const
+ {
+ if (m_invalid_value_is_valid)
+ return m_current_value != m_invalid_value;
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // This function will call the cleanup callback provided in the
+ // constructor one time if the value is considered valid (See is_valid()).
+ // This function sets m_callback_called to true so we don't call the
+ // cleanup callback multiple times on the same value.
+ //----------------------------------------------------------------------
+ void
+ clean()
+ {
+ if (m_callback && !m_callback_called)
+ {
+ m_callback_called = true;
+ if (is_valid())
+ m_callback(m_current_value);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Cancels the cleanup that would have been called on "m_current_value"
+ // if it was valid. This function can be used to release the value
+ // contained in this object so ownership can be transfered to the caller.
+ //----------------------------------------------------------------------
+ value_type
+ release ()
+ {
+ m_callback_called = true;
+ return m_current_value;
+ }
+
+private:
+ value_type m_current_value;
+ const value_type m_invalid_value;
+ CallbackType m_callback;
+ bool m_callback_called;
+ bool m_invalid_value_is_valid;
+
+ // Outlaw default constructor, copy constructor and the assignment operator
+ DISALLOW_COPY_AND_ASSIGN (CleanUp);
+};
+
+} // namespace lldb_utility
+
+#endif // #ifndef liblldb_CleanUp_h_
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index f0d4e3cc6f9..0581c424e1c 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -13,6 +13,7 @@
261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */; };
261B5A5511C3F2AD00AABD0A /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; };
262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; };
+ 264723A611FA076E00DE380C /* CleanUp.h in Headers */ = {isa = PBXBuildFile; fileRef = 264723A511FA076E00DE380C /* CleanUp.h */; };
265ABF6310F42EE900531910 /* DebugSymbols.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 265ABF6210F42EE900531910 /* DebugSymbols.framework */; };
2668020E115FD12C008E1FE4 /* lldb-defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7C2510F1B3BC00F91463 /* lldb-defines.h */; settings = {ATTRIBUTES = (Public, ); }; };
2668020F115FD12C008E1FE4 /* lldb-enumerations.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7C2610F1B3BC00F91463 /* lldb-enumerations.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -513,6 +514,7 @@
263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeSTLMap.h; path = include/lldb/Core/ThreadSafeSTLMap.h; sourceTree = "<group>"; };
264334381110F63100CDB6C6 /* ValueObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectRegister.cpp; path = source/Core/ValueObjectRegister.cpp; sourceTree = "<group>"; };
2643343A1110F63C00CDB6C6 /* ValueObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectRegister.h; path = include/lldb/Core/ValueObjectRegister.h; sourceTree = "<group>"; };
+ 264723A511FA076E00DE380C /* CleanUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CleanUp.h; path = include/lldb/Utility/CleanUp.h; sourceTree = "<group>"; };
264AD83711095BA600E0B039 /* CommandObjectLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectLog.cpp; path = source/Commands/CommandObjectLog.cpp; sourceTree = "<group>"; };
264AD83911095BBD00E0B039 /* CommandObjectLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectLog.h; path = source/Commands/CommandObjectLog.h; sourceTree = "<group>"; };
265ABF6210F42EE900531910 /* DebugSymbols.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DebugSymbols.framework; path = /System/Library/PrivateFrameworks/DebugSymbols.framework; sourceTree = "<absolute>"; };
@@ -1505,6 +1507,7 @@
2682F168115ED9C800CCFF99 /* Utility */ = {
isa = PBXGroup;
children = (
+ 264723A511FA076E00DE380C /* CleanUp.h */,
261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */,
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */,
26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */,
@@ -2206,6 +2209,7 @@
26D27CA011ED3A4E0024D721 /* ELFHeader.h in Headers */,
49E45FAA11F660DC008F7B28 /* ClangASTType.h in Headers */,
49BB309611F79450001A4197 /* TaggedASTType.h in Headers */,
+ 264723A611FA076E00DE380C /* CleanUp.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
OpenPOWER on IntegriCloud