Microsoft KB Archive/126709

From BetaArchive Wiki

PRB: Error on Win32s: R6016 - not enough space for thread data

Q126709



The information in this article applies to:


  • Microsoft Win32s versions 1.2, 1.25





SYMPTOMS

Spawning and closing an application repeatedly succeeds around 60 times, then the spawn fails with this error:

R6016 - not enough space for thread data



CAUSE

The thread local storage (TLS) is not freed by the system.

The failure occurs only if there is another Win32-based application active while you are doing the spawns. The message itself is not generated by Win32s. It is generated by the Microsoft C Run-time (CRT) libraries LIBC.LIB and LIBCMT.LIB.



RESOLUTION

In Win32s version 1.25, TLS indices are freed during module cleanup. The TLS index is owned by the application's main module, so that it is freed when the application terminates. This solves the problem for LIBC and LIBCMT.

There is a similar problem with MSVCRT20.DLL. This DLL version of the CRT allocates a new TLS index each time a process attaches to it. MSVCRT20 doesn't free the TLS indices when unloading. The system should free them. If only one application uses MSVCRT20 at a time, then the application can be spawned successfully up to about 60 times on Win32s version 1.20. On Win32s version 1.25, there is no limitation.

If there is already an active application that uses MSVCRT20, it is not possible to spawn and close a second application that uses MSVCRT20 more than about 60 times under Win32s version 1.25. This is because MSVCRT20 allocates a TLS index each time a process attaches to it. Win32s will free all of the TLS indices only when MSVCRT20 is unloaded.



MORE INFORMATION

On Win32s, TLS allocation should be done once and not per process. Each process can use the index to store per-process data, just as a thread uses a TLS index on Windows NT. This is easy to do, because DLL data is shared between all processes under Win32s.

The following example demonstrates how to do the TLS allocation once on Win32s:

   BOOL APIENTRY DllMain(HINSTANCE hinstDll, DWORD fdwReason,
           LPVOID lpvReserved)
   {
       static BOOL fFirstProcess = TRUE;
       BOOL fWin32s = FALSE;
       DWORD dwVersion = GetVersion();
       static DWORD dwIndex;

       if ( !(dwVersion & 0x80000000) && LOBYTE(LOWORD(dwVersion))<4 )
           fWin32s = TRUE;

       if (dwReason == DLL_PROCESS_ATTACH) {
           if (fFirstProcess || !fWin32s) {
               dwIndex = TlsAlloc();
            }
            fFirstProcess = FALSE;
       }
       .
       .
       .
   } 

Additional query words: 1.20

Keywords :
Issue type :
Technology : kbWin32sSearch kbWin32s120 kbWin32s125


Last Reviewed: January 12, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.