Share via


TLS Slot Limitation

The Microsoft Layer for Unicode (MSLU) requires a single thread local storage (TLS) slot to store thread-specific information. This is allocated at DLL_PROCESS_ATTACH time. There must be enough memory to allow this allocation in the process heap; if it fails, the .dll load fails and GetLastError returns ERROR_MAX_THRDS_REACHED.

The memory is allocated if you call any API that takes a function pointer, either for a hook function or a callback. There must be enough memory to allow this allocation in the process heap; if not, the function call fails with ERROR_OUTOFMEMORY. This is a one-time allocation. This involves the following functions:

ChooseColor
ChooseFont
EnumCalendarInfo
EnumCalendarInfoEx
EnumDateFormats
EnumDateFormatsEx
EnumFontFamilies
EnumFontFamiliesEx
EnumFonts
EnumICMProfiles

EnumProps
EnumPropsEx
EnumSystemLocales
EnumTimeFormats
GetOpenFileName
GetSaveFileName
FindText
PageSetupDlg
PrintDlg
ReplaceText

The TLS slot stores, among other things, pointers to wrapper versions of enumeration procs and hook functions. Thus, you can only specify one enumeration proc or hook function at a time, per function and per thread. In the enumeration case, the Microsoft Layer for Unicode properly counts the number of references for your function; for example, you can make a call inside of your EnumFontFamExProc callback to EnumFontFamiliesEx, as long as the two calls to the function use the same callback on your side. You can support up to 15 calls in a single thread. If you try to exceed this limit, the function call fails; GetLastError returns ERROR_INVALID_FILTER_PROC.

Currently, there is no such callback support for reference counting for a callback function from within the Comdlg32.dll wrappers; you may only have one of those calls per thread. MSLU fails the second call with the same error as previously mentioned.