| Index: base/win/scoped_handle.h
|
| diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h
|
| index 44e723f941a2b78af9a83a895be1d31eeef0f4c0..b89219c45ee3c8fdd6f9a07b3de1ad3b831d9129 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;
|
|
|