197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// Copyright 2014 The Android Open Source Project 297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// 397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// This software is licensed under the terms of the GNU General Public 497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// License version 2, as published by the Free Software Foundation, and 597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// may be copied, distributed, and modified under those terms. 697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// 797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// This program is distributed in the hope that it will be useful, 897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of 997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// GNU General Public License for more details. 1197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 1297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#ifndef ANDROID_BASE_FILES_SCOPED_HANDLE_H 1397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#define ANDROID_BASE_FILES_SCOPED_HANDLE_H 1497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 1597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#if !defined(_WIN32) && !defined(_WIN64) 1697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#error "Only compile this file when targetting Windows!" 1797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#endif 1897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 1997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#include "android/base/Compiler.h" 2097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 2197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#define WIN32_LEAN_AND_MEAN 1 2297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#include <windows.h> 2397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 2497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turnernamespace android { 2597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turnernamespace base { 2697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 2797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// Helper class used to wrap a Win32 HANDLE that will be closed when 2897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// the instance is destroyed, unless the release() method was called 2997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner// before that. 3097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turnerclass ScopedHandle { 3197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turnerpublic: 3297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Default destructor is used to wrap an invalid handle value. 3397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner ScopedHandle() : handle_(INVALID_HANDLE_VALUE) {} 3497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 3597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Constructor takes ownership of |handle|. 3697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner explicit ScopedHandle(HANDLE handle) : handle_(handle) {} 3797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 3897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Destructor calls close() method. 3997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner ~ScopedHandle() { close(); } 4097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 4197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Returns true iff the wrapped HANDLE value is valid. 4297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner bool valid() const { return handle_ != INVALID_HANDLE_VALUE; } 4397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 4497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Return current HANDLE value. Does _not_ transfer ownership. 4597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner HANDLE get() const { return handle_; } 4697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 4797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Return current HANDLE value, transferring ownership to the caller. 4897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner HANDLE release() { 4997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner HANDLE h = handle_; 5097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner handle_ = INVALID_HANDLE_VALUE; 5197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner return h; 5297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner } 5397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 5497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Close handle if it is not invalid. 5597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner void close() { 5697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner if (handle_ != INVALID_HANDLE_VALUE) { 5797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner ::CloseHandle(handle_); 5897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner handle_ = INVALID_HANDLE_VALUE; 5997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner } 6097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner } 6197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 6297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner // Swap the content of two ScopedHandle instances. 6397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner void swap(ScopedHandle* other) { 6497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner HANDLE handle = handle_; 6597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner handle_ = other->handle_; 6697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner other->handle_ = handle; 6797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner } 6897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 6997502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turnerprivate: 7097502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner DISALLOW_COPY_AND_ASSIGN(ScopedHandle); 7197502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 7297502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner HANDLE handle_; 7397502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner}; 7497502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 7597502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner} // namespace base 7697502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner} // namespace android 7797502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner 7897502faffa2e99bf717749a2d249ba3e57d7da4dDavid 'Digit' Turner#endif // ANDROID_BASE_FILES_SCOPED_HANDLE_H 79