Skip to content

Commit 4de3d9b

Browse files
authored
Bail out of infinite timeouts in our posix synchapi emulation (shader-slang#3129)
This can happen if vkd3d-proton triggered a VK_DEVICE_LOST
1 parent 8a292cf commit 4de3d9b

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

tools/gfx/d3d12/d3d12-posix-synchapi.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,19 @@ BOOL SetEvent(HANDLE h)
124124
}
125125
}
126126

127-
DWORD WaitForSingleObject(HANDLE h, DWORD ms)
127+
DWORD WaitForSingleObject(const HANDLE h, const DWORD ms)
128128
{
129129
int fd = _handleToFD(h);
130130
bool manualReset = _handleToFlags(h) & CREATE_EVENT_MANUAL_RESET;
131131
pollfd pfd{fd, POLLIN, 0};
132132
uint64_t x;
133133
int r = 0;
134-
int nEvents = poll(&pfd, 1, ms);
134+
// Implement unlimited waits as timing out with WAIT_FAILED after 5
135+
// seconds. It's probably something fishy with d3dvk-proton or our synchapi
136+
// implementation
137+
const bool isInfinite = ms == INFINITE;
138+
const DWORD fiveSeconds = 5000;
139+
int nEvents = poll(&pfd, 1, isInfinite ? fiveSeconds : ms);
135140
if(pfd.revents != POLLIN)
136141
{
137142
return WAIT_FAILED;
@@ -142,7 +147,7 @@ DWORD WaitForSingleObject(HANDLE h, DWORD ms)
142147
}
143148
if (nEvents == 0)
144149
{
145-
return WAIT_TIMEOUT;
150+
return isInfinite ? WAIT_FAILED : WAIT_TIMEOUT;
146151
}
147152
if(manualReset)
148153
{
@@ -155,7 +160,7 @@ DWORD WaitForSingleObject(HANDLE h, DWORD ms)
155160
}
156161
if(r == -1 && errno == EAGAIN)
157162
{
158-
return WAIT_TIMEOUT;
163+
return isInfinite ? WAIT_FAILED : WAIT_TIMEOUT;
159164
}
160165
return WAIT_FAILED;
161166
}
@@ -164,12 +169,19 @@ DWORD WaitForMultipleObjects(
164169
DWORD n,
165170
const HANDLE *hs,
166171
BOOL bWaitAll,
167-
DWORD dwMilliseconds)
172+
DWORD requestedMs)
168173
{
169174
if(n == 0)
170175
{
171176
return bWaitAll ? WAIT_OBJECT_0 : WAIT_FAILED;
172177
}
178+
179+
// Bail out of infinite waits after 5 seconds as it's probably a
180+
// driver/vkd3d-proton/synchapi bug
181+
const bool isInfinite = requestedMs == INFINITE;
182+
const DWORD fiveSeconds = 5000;
183+
const auto dwMilliseconds = isInfinite ? fiveSeconds : requestedMs;
184+
173185
DWORD res;
174186
int fds[n];
175187
int flagss[n];
@@ -281,7 +293,7 @@ DWORD WaitForMultipleObjects(
281293
// If we got here without seeing enough events, we must have timed out
282294
if(nSeenEvents < n)
283295
{
284-
res = WAIT_TIMEOUT;
296+
res = isInfinite ? WAIT_FAILED : WAIT_TIMEOUT;
285297
goto end;
286298
}
287299

@@ -415,7 +427,7 @@ DWORD WaitForMultipleObjects(
415427
}
416428
if(nEvents == 0)
417429
{
418-
res = WAIT_TIMEOUT;
430+
res = isInfinite ? WAIT_FAILED : WAIT_TIMEOUT;
419431
goto end;
420432
}
421433
// Try reads until we get one

0 commit comments

Comments
 (0)