1dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine/* 2dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * Copyright (C) 2006 The Android Open Source Project 3dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * 4dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * Licensed under the Apache License, Version 2.0 (the "License"); 5dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * you may not use this file except in compliance with the License. 6dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * You may obtain a copy of the License at 7dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * 8dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * http://www.apache.org/licenses/LICENSE-2.0 9dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * 10dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * Unless required by applicable law or agreed to in writing, software 11dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * distributed under the License is distributed on an "AS IS" BASIS, 12dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * See the License for the specific language governing permissions and 14dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine * limitations under the License. 15dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine */ 16dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 17dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine/** \file 18dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine This file consists of implementation of a class AdbObjectHandle that 19dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine encapsulates an internal API object that is visible to the outside 20dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine of the API through a handle. 21dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine*/ 22dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 23dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine#include "stdafx.h" 24dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine#include "adb_api.h" 25dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine#include "adb_object_handle.h" 26dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 27dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine/// Global ADBAPIHANDLE -> AdbObjectHandle* map 28dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineAdbObjectHandleMap the_map; 29dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 30dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine/// Locker for the AdbObjectHandleMap instance 31dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineCComAutoCriticalSection the_map_locker; 32dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 33dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine/// Next adb handle value generator 34dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineULONG_PTR next_adb_handle_value = 0; 35dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 36dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineAdbObjectHandle::AdbObjectHandle(AdbObjectType obj_type) 37dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine : adb_handle_(NULL), 38dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine object_type_(obj_type), 39dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ref_count_(1) { 40dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(obj_type < AdbObjectTypeMax); 41dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 42dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 43dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineAdbObjectHandle::~AdbObjectHandle() { 44dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(0 == ref_count_); 45dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(NULL == adb_handle_); 46dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 47dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 48dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineLONG AdbObjectHandle::AddRef() { 49dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(ref_count_ > 0); 50dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return InterlockedIncrement(&ref_count_); 51dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 52dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 53dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineLONG AdbObjectHandle::Release() { 54dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(ref_count_ > 0); 55dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine LONG ret = InterlockedDecrement(&ref_count_); 56dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(ret >= 0); 57dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine if (0 == ret) { 58dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine LastReferenceReleased(); 59dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine delete this; 60dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 61dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return ret; 62dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 63dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 64dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineADBAPIHANDLE AdbObjectHandle::CreateHandle() { 65dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ADBAPIHANDLE ret = NULL; 66dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 67dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // We have to hold this lock while we're dealing with the handle 68dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // and the table 69dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Lock(); 70dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 71dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(!IsOpened()); 72dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 73dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine if (!IsOpened()) { 74dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine try { 75dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Generate next handle value 76dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine next_adb_handle_value++; 77dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret = reinterpret_cast<ADBAPIHANDLE>(next_adb_handle_value); 78dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 79dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Add ourselves to the map 80dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map[ret] = this; 81dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 82dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Save handle, addref and return 83dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine adb_handle_ = ret; 84dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine AddRef(); 85dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } catch (...) { 86dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret = NULL; 87dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_OUTOFMEMORY); 88dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 89dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } else { 90dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Signaling that this object is already opened 91dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_GEN_FAILURE); 92dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 93dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 94dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Unlock(); 95dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 96dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return ret; 97dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 98dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 99dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkinebool AdbObjectHandle::CloseHandle() { 100dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine bool ret = false; 101dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 102dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Addref just in case that last reference to this object is being 103dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // held in the map 104dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine AddRef(); 105dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 106dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Lock(); 107dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 108dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(IsOpened()); 109dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 110dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine if (IsOpened()) { 111dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine try { 112dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Look us up in the map. 113dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine AdbObjectHandleMap::iterator found = the_map.find(adb_handle()); 114dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT((found != the_map.end()) && (this == found->second)); 115dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 116dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine if ((found != the_map.end()) && (this == found->second)) { 117dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Remove ourselves from the map, close and release the object 118dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map.erase(found); 119dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine adb_handle_ = NULL; 120dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine Release(); 121dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret = true; 122dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } else { 123dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_INVALID_HANDLE); 124dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 125dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } catch (...) { 126dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret = false; 127dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_OUTOFMEMORY); 128dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 129dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } else { 130dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_INVALID_HANDLE); 131dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 132dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 133dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Unlock(); 134dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 135dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine Release(); 136dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 137dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return ret; 138dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 139dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 140dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkinebool AdbObjectHandle::IsObjectOfType(AdbObjectType obj_type) const { 141dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return (obj_type == object_type()); 142dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 143dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 144dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkinevoid AdbObjectHandle::LastReferenceReleased() { 145dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ATLASSERT(!IsOpened()); 146dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 147dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 148dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkineAdbObjectHandle* AdbObjectHandle::Lookup(ADBAPIHANDLE adb_hndl) { 149dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine AdbObjectHandle* ret = NULL; 150dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 151dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Lock(); 152dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 153dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine try { 154dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine // Look us up in the map. 155dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine AdbObjectHandleMap::iterator found = the_map.find(adb_hndl); 156dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine if (found != the_map.end()) { 157dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret = found->second; 158dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine ret->AddRef(); 159dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 160dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } catch (...) { 161dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine SetLastError(ERROR_OUTOFMEMORY); 162dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine } 163dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 164dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine the_map_locker.Unlock(); 165dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine 166dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine return ret; 167dceaaa52cec11631c72cfea5fb74ee607602ecdevchtchetkine} 168