1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed deadlock in VirtualScreen::createSurface

This commit is contained in:
narzoul 2019-08-26 22:58:00 +02:00
parent 66e0d20897
commit d1cd6658c9
5 changed files with 20 additions and 24 deletions

View File

@ -24,27 +24,17 @@ namespace Compat
{ {
public: public:
ScopedCriticalSection(CRITICAL_SECTION& cs) ScopedCriticalSection(CRITICAL_SECTION& cs)
: m_cs(cs), m_isLocked(true) : m_cs(cs)
{ {
EnterCriticalSection(&m_cs); EnterCriticalSection(&m_cs);
} }
~ScopedCriticalSection() ~ScopedCriticalSection()
{ {
unlock(); LeaveCriticalSection(&m_cs);
}
void unlock()
{
if (m_isLocked)
{
LeaveCriticalSection(&m_cs);
m_isLocked = false;
}
} }
private: private:
CRITICAL_SECTION& m_cs; CRITICAL_SECTION& m_cs;
bool m_isLocked;
}; };
}; };

View File

@ -62,6 +62,7 @@ namespace
void bltToWindowViaGdi(Gdi::Region* primaryRegion) void bltToWindowViaGdi(Gdi::Region* primaryRegion)
{ {
D3dDdi::ScopedCriticalSection lock;
std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc); std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc);
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds(); RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();

View File

@ -1,15 +1,16 @@
#include "Common/CompatPtr.h" #include <Common/CompatPtr.h>
#include "D3dDdi/KernelModeThunks.h" #include <D3dDdi/KernelModeThunks.h>
#include "DDraw/DirectDrawClipper.h" #include <D3dDdi/ScopedCriticalSection.h>
#include "DDraw/DirectDrawPalette.h" #include <DDraw/DirectDrawClipper.h>
#include "DDraw/DirectDrawSurface.h" #include <DDraw/DirectDrawPalette.h>
#include "DDraw/RealPrimarySurface.h" #include <DDraw/DirectDrawSurface.h>
#include "DDraw/Surfaces/PrimarySurface.h" #include <DDraw/RealPrimarySurface.h>
#include "DDraw/Surfaces/PrimarySurfaceImpl.h" #include <DDraw/Surfaces/PrimarySurface.h>
#include "Dll/Procs.h" #include <DDraw/Surfaces/PrimarySurfaceImpl.h>
#include "Gdi/Gdi.h" #include <Dll/Procs.h>
#include "Gdi/Region.h" #include <Gdi/Gdi.h>
#include "Gdi/VirtualScreen.h" #include <Gdi/Region.h>
#include <Gdi/VirtualScreen.h>
namespace namespace
{ {
@ -29,6 +30,7 @@ namespace
return; return;
} }
D3dDdi::ScopedCriticalSection lock;
Gdi::Region clipRgn(DDraw::DirectDrawClipper::getClipRgn(*clipper)); Gdi::Region clipRgn(DDraw::DirectDrawClipper::getClipRgn(*clipper));
RECT monitorRect = D3dDdi::KernelModeThunks::getMonitorRect(); RECT monitorRect = D3dDdi::KernelModeThunks::getMonitorRect();
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds(); RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();

View File

@ -104,6 +104,7 @@ namespace
if (hasDisplayDcArg(params...)) if (hasDisplayDcArg(params...))
{ {
D3dDdi::ScopedCriticalSection lock;
const bool isReadOnlyAccess = !hasDisplayDcArg(getDestinationDc<OrigFuncPtr, origFunc>(params...)); const bool isReadOnlyAccess = !hasDisplayDcArg(getDestinationDc<OrigFuncPtr, origFunc>(params...));
Gdi::AccessGuard accessGuard(isReadOnlyAccess ? Gdi::ACCESS_READ : Gdi::ACCESS_WRITE); Gdi::AccessGuard accessGuard(isReadOnlyAccess ? Gdi::ACCESS_READ : Gdi::ACCESS_WRITE);
return LOG_RESULT(Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(replaceDc(params)...)); return LOG_RESULT(Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(replaceDc(params)...));
@ -140,6 +141,7 @@ namespace
} }
else else
{ {
D3dDdi::ScopedCriticalSection lock;
Gdi::AccessGuard accessGuard(Gdi::ACCESS_WRITE); Gdi::AccessGuard accessGuard(Gdi::ACCESS_WRITE);
return LOG_RESULT(CALL_ORIG_FUNC(ExtTextOutW)(replaceDc(hdc), x, y, options, lprect, lpString, c, lpDx)); return LOG_RESULT(CALL_ORIG_FUNC(ExtTextOutW)(replaceDc(hdc), x, y, options, lprect, lpString, c, lpDx));
} }

View File

@ -121,6 +121,7 @@ namespace Gdi
CompatPtr<IDirectDrawSurface7> createSurface(const RECT& rect) CompatPtr<IDirectDrawSurface7> createSurface(const RECT& rect)
{ {
DDraw::ScopedThreadLock ddLock; DDraw::ScopedThreadLock ddLock;
D3dDdi::ScopedCriticalSection driverLock;
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
auto desc = getSurfaceDesc(rect); auto desc = getSurfaceDesc(rect);