/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
class SalYieldMutex : public comphelper::SolarMutex
{ public: // for ImplSalYield() and ImplSalYieldMutexAcquireWithWait()
osl::Condition m_condition; /// for MsgWaitForMultipleObjects()
if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
{ // If we don't call these message, the Output from the // Java clients doesn't come in the right order
GdiFlush();
}
}
/// note: while VCL is fully up and running (other threads started and /// before shutdown), the main thread must acquire SolarMutex only via /// this function to avoid deadlock void SalYieldMutex::doAcquire( sal_uInt32 nLockCount )
{
WinSalInstance* pInst = GetSalData()->mpInstance; if ( pInst && pInst->IsMainThread() )
{ if ( pInst->m_nNoYieldLock ) return; // tdf#96887 If this is the main thread, then we must wait for two things: // - the yield mutex being unlocked // - SendMessage() being triggered // This can nicely be done using MsgWaitForMultipleObjects, which is called in // m_condition.wait(). The 2nd one is // needed because if we don't reschedule, then we create deadlocks if a // Window's create/destroy is called via SendMessage() from another thread. // Have a look at the osl_waitCondition implementation for more info. do { // Calling Condition::reset frequently turns out to be a little expensive, // and the vast majority of the time there is no contention, so first // try just acquiring the mutex. if (m_aMutex.tryToAcquire()) break; // reset condition *before* acquiring!
m_condition.reset(); if (m_aMutex.tryToAcquire()) break; // wait for SalYieldMutex::release() to set the condition
osl::Condition::Result res = m_condition.wait();
assert(osl::Condition::Result::result_ok == res);
(void) res;
} while ( true );
} else
m_aMutex.acquire();
++m_nCount;
--nLockCount;
void WinSalInstance::AfterAppInit()
{ // (1) Ideally this would be done at the place that creates the thread, but since this thread is normally // just the default/main thread, that is not possible. // (2) Don't do this on unix, where it causes tools like pstree on Linux to // confusingly report soffice.bin as VCL Main instead.
osl_setThreadName("VCL Main");
}
// probably can't be static, because of SalTimer friend? (static gives C4211) bool ImplSalYield(constbool bWait, constbool bHandleAllCurrentEvents)
{ // used to abort further message processing on tick count wraps static sal_uInt32 nLastTicks = 0;
// we should never yield in m_nNoYieldLock mode! constbool bNoYieldLock = (GetSalData()->mpInstance->m_nNoYieldLock > 0);
assert(!bNoYieldLock); if (bNoYieldLock) returnfalse;
// 0ms timeouts are handled out-of-bounds to prevent busy-locking the // event loop with timeout messages. // We ensure we never handle more than one timeout per call. // This way we'll always process a normal system message. if ( !bWasTimeoutMsg && pTimer && pTimer->IsDirectTimeout() )
{
pTimer->ImplHandleElapsedTimer();
bWasMsg = true;
}
nLastTicks = nCurTicks;
if ( bWait && !bWasMsg )
{ switch (GetMessageW(&aMsg, nullptr, 0, 0))
{ case -1:
SAL_WARN("vcl.schedule", "GetMessageW failed: " << comphelper::WindowsErrorString(GetLastError())); // should we std::abort() / SalAbort here? break; case 0:
SAL_INFO("vcl.schedule", "GetMessageW received WM_QUIT while waiting"); break; default:
bWasMsg = true;
TranslateMessage(&aMsg);
ImplSalDispatchMessage(&aMsg); break;
}
}
// If we enabled ForceRealTimer mode skipping our direct timeout processing, // mainly because some Windows API call spawns its own nested message loop, // switch back to our own processing (like after window resize or move) if ( pTimer )
pTimer->SetForceRealTimer( false );
case SAL_MSG_DESTROYHWND: // We only destroy the native window here. We do NOT destroy the SalFrame contained // in the structure (GetWindowPtr()). if (DestroyWindow(reinterpret_cast<HWND>(lParam)) == 0)
{
OSL_FAIL("DestroyWindow failed!"); // Failure: We remove the SalFrame from the window structure. So we avoid that // the window structure may contain an invalid pointer, once the SalFrame is deleted.
SetWindowPtr(reinterpret_cast<HWND>(lParam), nullptr);
} break;
// Note: Do not use PeekMessage(), despite the name it may dispatch events, // even with PM_NOREMOVE specified, which may lead to unwanted recursion.
if ( (nType & VCL_INPUT_ANY) == VCL_INPUT_ANY )
{ // revert bugfix for #108919# which never reported timeouts when called from the timer handler // which made the application completely unresponsive during background formatting if ( GetQueueStatus( QS_ALLEVENTS )) returntrue;
} else
{
UINT flags = 0;
// This code previously considered modifier keys as OTHER, // but that makes this hard to do without PeekMessage, // is inconsistent with the X11 backend, and I see no good reason. if ( nType & VclInputFlags::KEYBOARD )
flags |= QS_KEY;
if ( nType & VclInputFlags::MOUSE )
flags |= QS_MOUSE;
if ( nType & VclInputFlags::PAINT )
flags |= QS_PAINT;
if ( nType & VclInputFlags::TIMER )
flags |= QS_TIMER;
/** Add a file to the system shells recent document list if there is any. This function may have no effect under Unix because there is no standard API among the different desktop managers.
@param aFileUrl The file url of the document.
*/ void WinSalInstance::AddToRecentDocumentList(const OUString& rFileUrl, const OUString& /*rMimeType*/, const OUString& rDocumentService)
{ if (Application::IsHeadlessModeEnabled()) return;
SHAddToRecentDocs ( SHARD_APPIDINFO, &info ); return;
}
} // For whatever reason, we could not use the SHARD_APPIDINFO semantics
SHAddToRecentDocs(SHARD_PATHW, system_path.getStr());
}
}
int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo)
{ // Decide if an exception is a c++ (mostly UNO) exception or a process violation. // Depending on this information we pass process violations directly to our signal handler ... // and c++ (UNO) exceptions are sended to the following code on the current stack. // Problem behind: user32.dll sometime consumes exceptions/process violations .-) // see also #112221#
using LPFN_ISWOW64PROCESS2 = BOOL(WINAPI*)(HANDLE, USHORT*, USHORT*); auto fnIsWow64Process2 = reinterpret_cast<LPFN_ISWOW64PROCESS2>(
GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2")); if (fnIsWow64Process2)
fnIsWow64Process2(GetCurrentProcess(), &o3tl::temporary(USHORT()), &nNativeMachine);
if (nNativeMachine == IMAGE_FILE_MACHINE_UNKNOWN)
{ #if _WIN64
nNativeMachine = IMAGE_FILE_MACHINE_AMD64;
#else
BOOL isWow64 = FALSE;
IsWow64Process(GetCurrentProcess(), &isWow64);
if (isWow64)
nNativeMachine = IMAGE_FILE_MACHINE_AMD64; // 32-bit process on 64-bit Windows else
nNativeMachine = IMAGE_FILE_MACHINE_I386;
#endif
}
switch (nNativeMachine)
{ case IMAGE_FILE_MACHINE_I386: return u" X86_32"_ustr; case IMAGE_FILE_MACHINE_R3000: return u" R3000"_ustr; case IMAGE_FILE_MACHINE_R4000: return u" R4000"_ustr; case IMAGE_FILE_MACHINE_R10000: return u" R10000"_ustr; case IMAGE_FILE_MACHINE_WCEMIPSV2: return u" WCEMIPSV2"_ustr; case IMAGE_FILE_MACHINE_ALPHA: return u" ALPHA"_ustr; case IMAGE_FILE_MACHINE_SH3: return u" SH3"_ustr; case IMAGE_FILE_MACHINE_SH3DSP: return u" SH3DSP"_ustr; case IMAGE_FILE_MACHINE_SH3E: return u" SH3E"_ustr; case IMAGE_FILE_MACHINE_SH4: return u" SH4"_ustr; case IMAGE_FILE_MACHINE_SH5: return u" SH5"_ustr; case IMAGE_FILE_MACHINE_ARM: return u" ARM"_ustr; case IMAGE_FILE_MACHINE_THUMB: return u" THUMB"_ustr; case IMAGE_FILE_MACHINE_ARMNT: return u" ARMNT"_ustr; case IMAGE_FILE_MACHINE_AM33: return u" AM33"_ustr; case IMAGE_FILE_MACHINE_POWERPC: return u" POWERPC"_ustr; case IMAGE_FILE_MACHINE_POWERPCFP: return u" POWERPCFP"_ustr; case IMAGE_FILE_MACHINE_IA64: return u" IA64"_ustr; case IMAGE_FILE_MACHINE_MIPS16: return u" MIPS16"_ustr; case IMAGE_FILE_MACHINE_ALPHA64: return u" ALPHA64"_ustr; case IMAGE_FILE_MACHINE_MIPSFPU: return u" MIPSFPU"_ustr; case IMAGE_FILE_MACHINE_MIPSFPU16: return u" MIPSFPU16"_ustr; case IMAGE_FILE_MACHINE_TRICORE: return u" TRICORE"_ustr; case IMAGE_FILE_MACHINE_CEF: return u" CEF"_ustr; case IMAGE_FILE_MACHINE_EBC: return u" EBC"_ustr; case IMAGE_FILE_MACHINE_AMD64: return u" X86_64"_ustr; case IMAGE_FILE_MACHINE_M32R: return u" M32R"_ustr; case IMAGE_FILE_MACHINE_ARM64: return u" ARM64"_ustr; case IMAGE_FILE_MACHINE_CEE: return u" CEE"_ustr; default:
assert(!"Yet unhandled case"); return OUString();
}
}
static OUString getOSVersionString(DWORD nBuildNumber)
{
OUStringBuffer result = u"Windows"; if (nBuildNumber >= 22000)
result.append(" 11"); elseif (nBuildNumber > 0)
result.append(" 10"); else// We don't know what Windows it is
result.append(" unknown");
result.append(getWinArch());
if (nBuildNumber)
result.append(" (build " + OUString::number(nBuildNumber) + ")");
return result.makeStringAndClear();
}
DWORD WinSalInstance::getWindowsBuildNumber()
{ staticconst DWORD nResult = []
{
DWORD nBuildNumber = 0; // use RtlGetVersion to get build number if (HMODULE h_ntdll = GetModuleHandleW(L"ntdll.dll"))
{ if (auto RtlGetVersion
= reinterpret_cast<RtlGetVersion_t>(GetProcAddress(h_ntdll, "RtlGetVersion")))
{
RTL_OSVERSIONINFOW vi2{}; // initialize with zeroes - a better alternative to memset
vi2.dwOSVersionInfoSize = sizeof(vi2); if (STATUS_SUCCESS == RtlGetVersion(&vi2))
{
nBuildNumber = vi2.dwBuildNumber;
}
}
} return nBuildNumber;
}(); return nResult;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.