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

Article translations Article translations
Article ID: 126709 - View products that this article applies to.
This article was previously published under Q126709
Expand all | Collapse all

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;
       }
       .
       .
       .
   }
				

Properties

Article ID: 126709 - Last Review: October 30, 2003 - Revision: 3.0
APPLIES TO
  • Microsoft Win32s 1.2
  • Microsoft Win32s 1.25
Keywords: 
KB126709
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com