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