Use _beginthreadex instead of CreateThread

The documentation for ExitThread [1] has this comment:

  A thread in an executable that calls the C run-time library (CRT) should use
  the _beginthreadex and _endthreadex functions for thread management rather
  than CreateThread and ExitThread; this requires the use of the multithreaded
  version of the CRT. If a thread created using CreateThread calls the CRT,
  the CRT may terminate the process in low-memory conditions.

Since ~all our code uses CRT, be safe and use _beginthreadex.

[1] https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread

Change-Id: If3e566592e921b00240e08aa759d8cdbc421d44b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155513
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski 2023-08-09 14:29:54 +03:00
parent da54fbce1c
commit 8a0c43fa86
10 changed files with 37 additions and 38 deletions

View file

@ -18,6 +18,7 @@
*/
#include <systools/win32/uwinapi.h>
#include <process.h>
#include <tlhelp32.h>
#include <rpc.h>
#include <winsock.h>
@ -159,7 +160,7 @@ static DWORD GetParentProcessId()
return dwParentProcessId;
}
static DWORD WINAPI ParentMonitorThreadProc( LPVOID lpParam )
static unsigned __stdcall ParentMonitorThreadProc(void* lpParam)
{
DWORD_PTR dwParentProcessId = reinterpret_cast<DWORD_PTR>(lpParam);
@ -196,8 +197,6 @@ BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID )
if ( dwResult && dwResult < SAL_N_ELEMENTS(szBuffer) )
{
DWORD dwThreadId = 0;
DWORD_PTR dwParentProcessId = static_cast<DWORD_PTR>(_wtol( szBuffer ));
if ( dwParentProcessId && GetParentProcessId() == dwParentProcessId )
@ -205,8 +204,8 @@ BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID )
// No error check, it works or it does not
// Thread should only be started for headless mode, see desktop/win32/source/officeloader.cxx
HANDLE hThread
= CreateThread(nullptr, 0, ParentMonitorThreadProc,
reinterpret_cast<LPVOID>(dwParentProcessId), 0, &dwThreadId);
= reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, ParentMonitorThreadProc,
reinterpret_cast<LPVOID>(dwParentProcessId), 0, nullptr));
// Note: calling CreateThread in DllMain is discouraged
// but this is only done in the headless mode and in
// that case no other threads should be running at startup

View file

@ -43,7 +43,7 @@ namespace {
typedef struct
{
HANDLE m_hThread; /* OS-handle used for all thread-functions */
DWORD m_ThreadId; /* identifier for this thread */
unsigned m_ThreadId; /* identifier for this thread */
sal_Int32 m_nTerminationRequested;
oslWorkerFunction m_WorkerFunction;
void* m_pData;
@ -54,7 +54,7 @@ typedef struct
static oslThread oslCreateThread(oslWorkerFunction pWorker, void* pThreadData, sal_uInt32 nFlags);
static DWORD WINAPI oslWorkerWrapperFunction(_In_ LPVOID pData)
static unsigned __stdcall oslWorkerWrapperFunction(void* pData)
{
osl_TThreadImpl* pThreadImpl= static_cast<osl_TThreadImpl*>(pData);
@ -89,13 +89,13 @@ static oslThread oslCreateThread(oslWorkerFunction pWorker,
pThreadImpl->m_pData= pThreadData;
pThreadImpl->m_nTerminationRequested= 0;
pThreadImpl->m_hThread= CreateThread(
pThreadImpl->m_hThread= reinterpret_cast<HANDLE>(_beginthreadex(
nullptr, /* no security */
0, /* default stack-size */
oslWorkerWrapperFunction, /* worker-function */
pThreadImpl, /* provide worker-function with data */
nFlags, /* start thread immediately or suspended */
&pThreadImpl->m_ThreadId);
&pThreadImpl->m_ThreadId));
if(pThreadImpl->m_hThread == nullptr)
{

View file

@ -426,7 +426,7 @@ static LRESULT CALLBACK executerWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LP
}
static DWORD WINAPI SystrayThread( LPVOID /*lpParam*/ )
static unsigned __stdcall SystrayThread(void* /*lpParam*/)
{
osl_setThreadName("SystrayThread");
@ -516,8 +516,8 @@ void win32_init_sys_tray()
nullptr // window-creation data
);
DWORD dwThreadId;
CloseHandle(CreateThread(nullptr, 0, SystrayThread, nullptr, 0, &dwThreadId));
CloseHandle(reinterpret_cast<HANDLE>(
_beginthreadex(nullptr, 0, SystrayThread, nullptr, 0, nullptr)));
}
}

View file

@ -43,6 +43,7 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Winhttp.h>
#include <process.h>
#endif
using namespace com::sun::star;
@ -460,7 +461,7 @@ struct GetPACProxyData
// Tries to get proxy configuration using WinHttpGetProxyForUrl, which supports Web Proxy Auto-Discovery
// (WPAD) protocol and manually configured address to get Proxy Auto-Configuration (PAC) file.
// The WinINet/WinHTTP functions cannot correctly run in a STA COM thread, so use a dedicated thread
DWORD WINAPI GetPACProxyThread(_In_ LPVOID lpParameter)
unsigned __stdcall GetPACProxyThread(void* lpParameter)
{
assert(lpParameter);
GetPACProxyData* pData = static_cast<GetPACProxyData*>(lpParameter);
@ -557,7 +558,8 @@ InternetProxyServer GetPACProxy(const OUString& rProtocol, const OUString& rHost
}
}
HANDLE hThread = CreateThread(nullptr, 0, GetPACProxyThread, &aData, 0, nullptr);
HANDLE hThread = reinterpret_cast<HANDLE>(
_beginthreadex(nullptr, 0, GetPACProxyThread, &aData, 0, nullptr));
if (hThread)
{
WaitForSingleObject(hThread, INFINITE);

View file

@ -54,7 +54,7 @@ class DropTarget : public cppu::BaseMutex,
{
private:
friend DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams);
friend unsigned __stdcall DndTargetOleSTAFunc(void* pParams);
// The native window which acts as drop target.
// It is set in initialize. In case RegisterDragDrop fails it is set
// to NULL
@ -65,7 +65,7 @@ private:
DWORD m_threadIdWindow;
// This is the thread id of the OLE thread that is created in DropTarget::initialize
// when the calling thread is an MTA
DWORD m_threadIdTarget;
unsigned m_threadIdTarget;
// The handle of the thread that is created in DropTarget::initialize
// when the calling thread is an MTA
HANDLE m_hOleThread;

View file

@ -634,7 +634,7 @@ struct WorkerThreadData
#ifdef _WIN32
static HANDLE hThreadID = nullptr;
static DWORD WINAPI threadmain( _In_ LPVOID pArgs )
static unsigned __stdcall threadmain(void* pArgs)
{
OleInitialize( nullptr );
static_cast<WorkerThreadData*>(pArgs)->pWorker( static_cast<WorkerThreadData*>(pArgs)->pThreadData );
@ -661,14 +661,13 @@ void CreateMainLoopThread( oslWorkerFunction pWorker, void * pThreadData )
#ifdef _WIN32
// sal thread always call CoInitializeEx, so a system dependent implementation is necessary
DWORD uThreadID;
hThreadID = CreateThread(
hThreadID = reinterpret_cast<HANDLE>(_beginthreadex(
nullptr, // no security handle
0, // stacksize 0 means default
threadmain, // thread worker function
new WorkerThreadData( pWorker, pThreadData ), // arguments for worker function
0, // 0 means: create immediately otherwise use CREATE_SUSPENDED
&uThreadID ); // thread id to fill
nullptr )); // thread id to fill
#else
hThreadID = osl_createThread( MainWorkerFunction, new WorkerThreadData( pWorker, pThreadData ) );
#endif

View file

@ -241,8 +241,8 @@ CMtaOleClipboard::CMtaOleClipboard( ) :
s_theMtaOleClipboardInst = this;
m_hOleThread = CreateThread(
nullptr, 0, CMtaOleClipboard::oleThreadProc, this, 0, &m_uOleThreadId );
m_hOleThread = reinterpret_cast<HANDLE>(_beginthreadex(
nullptr, 0, CMtaOleClipboard::oleThreadProc, this, 0, &m_uOleThreadId ));
OSL_ASSERT( nullptr != m_hOleThread );
// setup the clipboard changed notifier thread
@ -253,9 +253,8 @@ CMtaOleClipboard::CMtaOleClipboard( ) :
m_hClipboardChangedNotifierEvents[1] = CreateEventW( nullptr, MANUAL_RESET, INIT_NONSIGNALED, nullptr );
OSL_ASSERT( nullptr != m_hClipboardChangedNotifierEvents[1] );
DWORD uThreadId;
m_hClipboardChangedNotifierThread = CreateThread(
nullptr, 0, CMtaOleClipboard::clipboardChangedNotifierThreadProc, this, 0, &uThreadId );
m_hClipboardChangedNotifierThread = reinterpret_cast<HANDLE>(_beginthreadex(
nullptr, 0, CMtaOleClipboard::clipboardChangedNotifierThreadProc, this, 0, nullptr ));
OSL_ASSERT( nullptr != m_hClipboardChangedNotifierThread );
}
@ -675,7 +674,7 @@ unsigned int CMtaOleClipboard::run( )
return nRet;
}
DWORD WINAPI CMtaOleClipboard::oleThreadProc( _In_ LPVOID pParam )
unsigned __stdcall CMtaOleClipboard::oleThreadProc( void* pParam )
{
osl_setThreadName("CMtaOleClipboard::run()");
@ -686,7 +685,7 @@ DWORD WINAPI CMtaOleClipboard::oleThreadProc( _In_ LPVOID pParam )
return pInst->run( );
}
DWORD WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( _In_ LPVOID pParam )
unsigned __stdcall CMtaOleClipboard::clipboardChangedNotifierThreadProc(void* pParam)
{
osl_setThreadName("CMtaOleClipboard::clipboardChangedNotifierThreadProc()");
CMtaOleClipboard* pInst = static_cast< CMtaOleClipboard* >( pParam );

View file

@ -75,15 +75,15 @@ private:
LRESULT onClipboardUpdate();
static LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static DWORD WINAPI oleThreadProc( _In_ LPVOID pParam );
static unsigned __stdcall oleThreadProc(void* pParam);
static DWORD WINAPI clipboardChangedNotifierThreadProc( _In_ LPVOID pParam );
static unsigned __stdcall clipboardChangedNotifierThreadProc(void* pParam);
bool WaitForThreadReady( ) const;
private:
HANDLE m_hOleThread;
DWORD m_uOleThreadId;
unsigned m_uOleThreadId;
HANDLE m_hEvtThrdReady;
HWND m_hwndMtaOleReqWnd;
HANDLE m_hEvtWndDisposed;

View file

@ -48,7 +48,7 @@ using namespace com::sun::star::awt::MouseButton;
using namespace com::sun::star::awt;
using namespace com::sun::star::lang;
static DWORD WINAPI DndOleSTAFunc(_In_ LPVOID pParams);
static unsigned __stdcall DndOleSTAFunc(void* pParams);
DragSource::DragSource( const Reference<XComponentContext>& rxContext):
WeakComponentImplHelper< XDragSource, XInitialization, XServiceInfo >(m_aMutex),
@ -120,8 +120,8 @@ void DragSource::StartDragImpl(
// The thread accesses members of this instance but does not call acquire.
// Hopefully this instance is not destroyed before the thread has terminated.
DWORD threadId;
HANDLE hThread = CreateThread(nullptr, 0, DndOleSTAFunc, this, 0, &threadId);
HANDLE hThread
= reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, DndOleSTAFunc, this, 0, nullptr));
// detach from thread
CloseHandle(hThread);
@ -304,7 +304,7 @@ dtrans_DragSource_get_implementation(
carries out a drag and drop operation by calling
DoDragDrop. The thread also notifies all
XSourceListener. */
DWORD WINAPI DndOleSTAFunc(_In_ LPVOID pParams)
unsigned __stdcall DndOleSTAFunc(void* pParams)
{
osl_setThreadName("DragSource DndOleSTAFunc");

View file

@ -44,7 +44,7 @@ using namespace com::sun::star::datatransfer::dnd::DNDConstants;
#define WM_REGISTERDRAGDROP WM_USER + 1
#define WM_REVOKEDRAGDROP WM_USER + 2
DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams);
unsigned __stdcall DndTargetOleSTAFunc(void* pParams);
DropTarget::DropTarget( const Reference<XComponentContext>& rxContext):
WeakComponentImplHelper<XInitialization,XDropTarget, XServiceInfo>(m_aMutex),
@ -146,8 +146,8 @@ void SAL_CALL DropTarget::initialize( const Sequence< Any >& aArguments )
// It indicates that the thread is ready to receive messages.
HANDLE m_evtThreadReady= CreateEventW( nullptr, FALSE, FALSE, nullptr);
m_hOleThread= CreateThread( nullptr, 0, DndTargetOleSTAFunc,
&m_evtThreadReady, 0, &m_threadIdTarget);
m_hOleThread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, DndTargetOleSTAFunc,
&m_evtThreadReady, 0, &m_threadIdTarget));
WaitForSingleObject( m_evtThreadReady, INFINITE);
CloseHandle( m_evtThreadReady);
PostThreadMessageW( m_threadIdTarget, WM_REGISTERDRAGDROP, reinterpret_cast<WPARAM>(this), 0);
@ -190,7 +190,7 @@ void SAL_CALL DropTarget::initialize( const Sequence< Any >& aArguments )
// This function is called as extra thread from DragSource::startDrag.
// The function carries out a drag and drop operation by calling
// DoDragDrop. The thread also notifies all XSourceListener.
DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams)
unsigned __stdcall DndTargetOleSTAFunc(void* pParams)
{
osl_setThreadName("DropTarget DndTargetOleSTAFunc");