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; case0:
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. ThisfunctionmayhavenoeffectunderUnixbecausethereisno standardAPIamongthedifferentdesktopmanagers.
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.