ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

handle.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.