Sync & queriesGL 3.2

glClientWaitSync

Makes the CPU wait (up to a timeout) until a fence is signalled, or just checks it with timeout 0.

Signature

GLenum glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);

How it works

Blocks the calling thread until the fence signals or timeout nanoseconds pass. With a ring of three regions the fence is almost always signalled already, so the wait costs nothing; if it is not, the wait is the right thing to do, because the GPU is still reading the memory you want to change.

With timeout 0 it does not wait at all: a cheap way to poll, for example to check whether a readback is ready before mapping it.

Parameters

syncGLsync

The fence from glFenceSync.

flagsGLbitfield

GL_SYNC_FLUSH_COMMANDS_BIT (recommended) or 0.

timeoutGLuint64

Maximum wait in nanoseconds (1'000'000 = 1 ms). 0 = just check.

Return value

GL_ALREADY_SIGNALED (it was done before the call), GL_CONDITION_SATISFIED (it became done during the wait), GL_TIMEOUT_EXPIRED (still not done), or GL_WAIT_FAILED (an error).

Tips & pitfalls

  • Without GL_SYNC_FLUSH_COMMANDS_BIT the fence may still be sitting in a driver queue that was never sent to the GPU, and the wait can last until the timeout.

  • glWaitSync is the GPU-side version: it makes the GPU, not the CPU, wait (useful between two contexts).

Errors

When the call is invalid it does nothing and sets an error, which glGetError returns:

GL_INVALID_VALUE
sync is not a fence, or flags has unknown bits.

Example

example.cpp
1if (fence[k]) {
2    while (glClientWaitSync(fence[k], GL_SYNC_FLUSH_COMMANDS_BIT, 1'000'000) == GL_TIMEOUT_EXPIRED) {}
3    glDeleteSync(fence[k]);
4}
5memcpy(mapped + k * regionSize, data, regionSize);   // safe now
Official Khronos documentation