usp10 #1/2: create HandleTables to keep track of memory allocation.

Jeff L lats at yless4u.com.au
Wed Nov 8 04:01:00 CST 2006


Rob, as the HandleTable was your suggestion, could you provide a comment 
on whether these patches are a practical way forward?

Jeff Latimer

Jeff Latimer wrote:
> These 2 patches implement HandleTables for tracking memory usage for 
> the SCRIPT_STRING_ANALYSIS pointer.  The problem is that the ssa can 
> be copied to another pointer and NULL'ing the pointer is not a 
> reliable means of de-allocating the pointer.  The use of HandleTables 
> looks like a solution to the problem but it depends on whether storing 
> a handle in the ssa pointer is acceptable.  The table is of fixed size 
> which is another potential problem but tests indicate that the number 
> of handles in use will remain relatively small by comparison to the 
> table size.
>
> Advice is welcome.
>
> Jeff Latimer
>
> Changelog:
> Create HandleTables to keep track of memory allocation
> ---
>  dlls/usp10/Makefile.in |    2 +
>  dlls/usp10/usp10.c     |   71 
> +++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 70 insertions(+), 3 deletions(-)
> ------------------------------------------------------------------------
>
> diff --git a/dlls/usp10/Makefile.in b/dlls/usp10/Makefile.in
> index 9d716d5..edef33a 100644
> --- a/dlls/usp10/Makefile.in
> +++ b/dlls/usp10/Makefile.in
> @@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
>  VPATH     = @srcdir@
>  MODULE    = usp10.dll
>  IMPORTLIB = libusp10.$(IMPLIBEXT)
> -IMPORTS   = gdi32 kernel32
> +IMPORTS   = gdi32 ntdll kernel32
>  
>  C_SRCS = \
>  	usp10.c
> diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
> index 9fd6c1e..4b15047 100644
> --- a/dlls/usp10/usp10.c
> +++ b/dlls/usp10/usp10.c
> @@ -30,6 +30,7 @@ #include "wingdi.h"
>  #include "winuser.h"
>  #include "winnls.h"
>  #include "usp10.h"
> +#include "winternl.h"
>  
>  #include "wine/debug.h"
>  
> @@ -73,17 +74,83 @@ typedef struct scriptcache {
>         HDC hdc;
>  } Scriptcache;
>  
> +typedef struct _CACHE_HANDLE
> +{
> +    RTL_HANDLE RtlHandle;
> +    void * Cache_Address;
> +} CACHE_HANDLE;
> +
> +DWORD TlsIndex;                       /* Adress of shared memory  */
> +
>  /***********************************************************************
>   *      DllMain
>   *
> + * In this DllMain storage is allocated to each thread so that a HandleTable can
> + * be created and maintained thread safe.
> + *
> + * NOTES
> + *  The Tls functions (TlsAlloc, TlsSetValue, TlsGetValue and TlsFree) provide
> + *  access to the local thread storage.
> + *
> + *  LocalAlloc and LocalFree are used as in the Microsoft examples to access 
> + *  local thread storage.
> + *
> + *  RtlInitializeHandleTable initialises the handle table to a fixed size of 
> + *  entries to contain the addresses of the cache pointers used in the
> + *  ScriptString... functions.  This function is fairly light weight as the 
> + *  space for the handle table entries is not allocated at this time but waits
> + *  until the first RtlAllocateHandle call.  Hence only the functions that need
> + *  the handles incur the additional expense.
>   */
>  BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
>  {
> +    RTL_HANDLE_TABLE *Cache_HandleTable;
> +    BOOL Return_flag;
> +
>      switch(fdwReason) {
> +        /*
> +         * When the dll is loaded obtain a TlsIndex so that the HandleTable
> +         * pointer can be stored there uniquely for each thread.
> +         */
>          case DLL_PROCESS_ATTACH:
> -            DisableThreadLibraryCalls(hInstDLL);
> -	    break;
> +            if  ((TlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
> +                return FALSE;
> +        /* Fall though to THREAD_ATTACH as loading a DLL only drives 
> +         * DLL_PROCESS_ATTACHand not DLL_THREAD_ATTACH.  Here we allocate space
> +         * for the HandleTable from the thread local storage, save the pointer in
> +         * the Tls and intialise the table.
> +         */
> +        case DLL_THREAD_ATTACH:
> +            Cache_HandleTable = LocalAlloc(LPTR, sizeof(RTL_HANDLE_TABLE));
> +            if  (Cache_HandleTable)
> +            {
> +                Return_flag = TlsSetValue(TlsIndex, Cache_HandleTable);
> +                RtlInitializeHandleTable(0x3FFF, sizeof(CACHE_HANDLE), Cache_HandleTable);
> +            }
> +            break;
> +        /*
> +         * At exit from a thread, clean up HandleTable which includes freeing the
> +         * associated memory for handles and the HandleTable.
> +         */
> +        case DLL_THREAD_DETACH:
> +            Cache_HandleTable = TlsGetValue(TlsIndex);
> +            if  (Cache_HandleTable)
> +            {
> +                RtlDestroyHandleTable(Cache_HandleTable);
> +                LocalFree(Cache_HandleTable);
> +            }
> +            break;
> +        /*
> +         * As for DLL_THREAD_DETACH but includes freeing the TlsIndex.
> +         */
>  	case DLL_PROCESS_DETACH:
> +            Cache_HandleTable = TlsGetValue(TlsIndex);
> +            if  (Cache_HandleTable)
> +            {
> +                RtlDestroyHandleTable(Cache_HandleTable);
> +                LocalFree(Cache_HandleTable);
> +            }
> +            TlsFree(TlsIndex);
>  	    break;
>      }
>      return TRUE;
>
>   
> ------------------------------------------------------------------------
>
>
>   




More information about the wine-devel mailing list