diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 20:07:11 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 20:07:11 +0000 |
commit | 5f29c1d65b7eae25a84ce75b4147ebe5bbe4a45b (patch) | |
tree | 3ee118ee70d9a83166c5c74b149d0c83fab080a2 /base/win | |
parent | 930792991d819c4c14c62778731ff0dbde5ea159 (diff) | |
download | chromium_src-5f29c1d65b7eae25a84ce75b4147ebe5bbe4a45b.zip chromium_src-5f29c1d65b7eae25a84ce75b4147ebe5bbe4a45b.tar.gz chromium_src-5f29c1d65b7eae25a84ce75b4147ebe5bbe4a45b.tar.bz2 |
Making GenericScopedHandle capable of handling handle types other than HANDLE.
Review URL: http://codereview.chromium.org/9582045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124980 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/win')
-rw-r--r-- | base/win/scoped_handle.h | 93 |
1 files changed, 53 insertions, 40 deletions
diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h index 44e723f..b89219c 100644 --- a/base/win/scoped_handle.h +++ b/base/win/scoped_handle.h @@ -14,87 +14,100 @@ namespace base { namespace win { -// Used so we always remember to close the handle. -// The class interface matches that of ScopedStdioHandle in addition to an -// IsValid() method since invalid handles on windows can be either NULL or -// INVALID_HANDLE_VALUE (-1). -// -// Example: -// ScopedHandle hfile(CreateFile(...)); -// if (!hfile.Get()) -// ...process error -// ReadFile(hfile.Get(), ...); -// -// To sqirrel the handle away somewhere else: -// secret_handle_ = hfile.Take(); -// -// To explicitly close the handle: -// hfile.Close(); +// Generic wrapper for raw handles that takes care of closing handles +// automatically. The class interface follows the style of +// the ScopedStdioHandle class with a few additions: +// - IsValid() method can tolerate multiple invalid handle values such as NULL +// and INVALID_HANDLE_VALUE (-1) for Win32 handles. +// - Receive() method allows to receive a handle value from a function that +// takes a raw handle pointer only. template <class Traits> class GenericScopedHandle { public: - GenericScopedHandle() : handle_(NULL) { - } + typedef typename Traits::Handle Handle; + + GenericScopedHandle() : handle_(Traits::NullHandle()) {} - explicit GenericScopedHandle(HANDLE h) : handle_(NULL) { - Set(h); + explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { + Set(handle); } ~GenericScopedHandle() { Close(); } - // Use this instead of comparing to INVALID_HANDLE_VALUE to pick up our NULL - // usage for errors. bool IsValid() const { - return handle_ != NULL; + return Traits::IsHandleValid(handle_); } - void Set(HANDLE new_handle) { - Close(); + void Set(Handle handle) { + if (handle_ != handle) { + Close(); - // Windows is inconsistent about invalid handles, so we always use NULL - if (new_handle != INVALID_HANDLE_VALUE) - handle_ = new_handle; + if (Traits::IsHandleValid(handle)) { + handle_ = handle; + } + } } - HANDLE Get() { + Handle Get() const { return handle_; } - operator HANDLE() { return handle_; } + operator Handle() const { + return handle_; + } - HANDLE* Receive() { - DCHECK(!handle_) << "Handle must be NULL"; + Handle* Receive() { + DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; return &handle_; } - HANDLE Take() { - // transfers ownership away from this object - HANDLE h = handle_; - handle_ = NULL; - return h; + // Transfers ownership away from this object. + Handle Take() { + Handle temp = handle_; + handle_ = Traits::NullHandle(); + return temp; } + // Explicitly closes the owned handle. void Close() { - if (handle_) { + if (Traits::IsHandleValid(handle_)) { if (!Traits::CloseHandle(handle_)) { NOTREACHED(); } - handle_ = NULL; + handle_ = Traits::NullHandle(); } } private: - HANDLE handle_; + Handle handle_; + DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); }; +// The traits class for Win32 handles that can be closed via CloseHandle() API. class HandleTraits { public: + typedef HANDLE Handle; + + // Closes the handle. static bool CloseHandle(HANDLE handle) { return ::CloseHandle(handle) != FALSE; } + + // Returns true if the handle value is valid. + static bool IsHandleValid(HANDLE handle) { + return handle != NULL && handle != INVALID_HANDLE_VALUE; + } + + // Returns NULL handle value. + static HANDLE NullHandle() { + return NULL; + } + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); }; typedef GenericScopedHandle<HandleTraits> ScopedHandle; |