diff options
| -rw-r--r-- | lldb/include/lldb/Utility/CleanUp.h | 188 | ||||
| -rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 4 |
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; }; |

