Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhandle.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Hans Leidekker for CodeWeavers 00003 * 00004 * Based on the handle implementation from wininet. 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 #include "wine/port.h" 00023 #include "wine/debug.h" 00024 00025 #include <stdarg.h> 00026 00027 #include "windef.h" 00028 #include "winbase.h" 00029 #include "winhttp.h" 00030 00031 #include "winhttp_private.h" 00032 00033 WINE_DEFAULT_DEBUG_CHANNEL(winhttp); 00034 00035 #define HANDLE_CHUNK_SIZE 0x10 00036 00037 static CRITICAL_SECTION handle_cs; 00038 static CRITICAL_SECTION_DEBUG handle_cs_debug = 00039 { 00040 0, 0, &handle_cs, 00041 { &handle_cs_debug.ProcessLocksList, &handle_cs_debug.ProcessLocksList }, 00042 0, 0, { (ULONG_PTR)(__FILE__ ": handle_cs") } 00043 }; 00044 static CRITICAL_SECTION handle_cs = { &handle_cs_debug, -1, 0, 0, 0, 0 }; 00045 00046 static object_header_t **handles; 00047 static ULONG_PTR next_handle; 00048 static ULONG_PTR max_handles; 00049 00050 object_header_t *addref_object( object_header_t *hdr ) 00051 { 00052 ULONG refs = InterlockedIncrement( &hdr->refs ); 00053 TRACE("%p -> refcount = %d\n", hdr, refs); 00054 return hdr; 00055 } 00056 00057 object_header_t *grab_object( HINTERNET hinternet ) 00058 { 00059 object_header_t *hdr = NULL; 00060 ULONG_PTR handle = (ULONG_PTR)hinternet; 00061 00062 EnterCriticalSection( &handle_cs ); 00063 00064 if ((handle > 0) && (handle <= max_handles) && handles[handle - 1]) 00065 hdr = addref_object( handles[handle - 1] ); 00066 00067 LeaveCriticalSection( &handle_cs ); 00068 00069 TRACE("handle 0x%lx -> %p\n", handle, hdr); 00070 return hdr; 00071 } 00072 00073 void release_object( object_header_t *hdr ) 00074 { 00075 ULONG refs = InterlockedDecrement( &hdr->refs ); 00076 TRACE("object %p refcount = %d\n", hdr, refs); 00077 if (!refs) 00078 { 00079 if (hdr->type == WINHTTP_HANDLE_TYPE_REQUEST) close_connection( (request_t *)hdr ); 00080 00081 send_callback( hdr, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, &hdr->handle, sizeof(HINTERNET) ); 00082 00083 TRACE("destroying object %p\n", hdr); 00084 if (hdr->type != WINHTTP_HANDLE_TYPE_SESSION) list_remove( &hdr->entry ); 00085 hdr->vtbl->destroy( hdr ); 00086 } 00087 } 00088 00089 HINTERNET alloc_handle( object_header_t *hdr ) 00090 { 00091 object_header_t **p; 00092 ULONG_PTR handle = 0, num; 00093 00094 list_init( &hdr->children ); 00095 00096 EnterCriticalSection( &handle_cs ); 00097 if (!max_handles) 00098 { 00099 num = HANDLE_CHUNK_SIZE; 00100 if (!(p = heap_alloc_zero( sizeof(ULONG_PTR) * num ))) goto end; 00101 handles = p; 00102 max_handles = num; 00103 } 00104 if (max_handles == next_handle) 00105 { 00106 num = max_handles + HANDLE_CHUNK_SIZE; 00107 if (!(p = heap_realloc_zero( handles, sizeof(ULONG_PTR) * num ))) goto end; 00108 handles = p; 00109 max_handles = num; 00110 } 00111 handle = next_handle; 00112 if (handles[handle]) ERR("handle isn't free but should be\n"); 00113 00114 handles[handle] = addref_object( hdr ); 00115 while (handles[next_handle] && (next_handle < max_handles)) next_handle++; 00116 00117 end: 00118 LeaveCriticalSection( &handle_cs ); 00119 return hdr->handle = (HINTERNET)(handle + 1); 00120 } 00121 00122 BOOL free_handle( HINTERNET hinternet ) 00123 { 00124 BOOL ret = FALSE; 00125 ULONG_PTR handle = (ULONG_PTR)hinternet; 00126 object_header_t *hdr = NULL, *child, *next; 00127 00128 EnterCriticalSection( &handle_cs ); 00129 00130 if ((handle > 0) && (handle <= max_handles)) 00131 { 00132 handle--; 00133 if (handles[handle]) 00134 { 00135 hdr = handles[handle]; 00136 TRACE("destroying handle 0x%lx for object %p\n", handle + 1, hdr); 00137 handles[handle] = NULL; 00138 ret = TRUE; 00139 } 00140 } 00141 00142 LeaveCriticalSection( &handle_cs ); 00143 00144 if (hdr) 00145 { 00146 LIST_FOR_EACH_ENTRY_SAFE( child, next, &hdr->children, object_header_t, entry ) 00147 { 00148 TRACE("freeing child handle %p for parent handle 0x%lx\n", child->handle, handle + 1); 00149 free_handle( child->handle ); 00150 } 00151 release_object( hdr ); 00152 } 00153 00154 EnterCriticalSection( &handle_cs ); 00155 if (next_handle > handle && !handles[handle]) next_handle = handle; 00156 LeaveCriticalSection( &handle_cs ); 00157 00158 return ret; 00159 } Generated on Sat May 26 2012 04:22:59 for ReactOS by
1.7.6.1
|