Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
152621 stories
·
33 followers

Developing a cross-process reader/writer lock with limited readers, part 1: A semaphore

1 Share

Say you want to have the functionality of a reader/writer lock, but have it work cross-process. The built-in SRWLOCK works only within a single process. Can we build a reader/writer lock that works across processes?

For convenience, let’s say that you want to support a maximum of N simultaneous readers, for some fixed value N. We can do this:

  • Create a semaphore with a token count of N. Share this semaphore with all of the processes, either by giving it a name or by duplicating the handle into each of the processes.
  • To take a read lock, claim one token from the semaphore. To release the lock, release the token.
  • To take a write lock, claim N tokens from the semaphore. To release the lock, release N tokens.

The idea for the write lock is that it’s accomplished by claiming all the read locks, thereby ensuring that nobody else can get a read lock.

#define MAX_SHARED 100
HANDLE sharedSemaphore;

void AcquireShared()
{
    WaitForSingleObject(sharedSemaphore, INFINITE);
}

void ReleaseShared()
{
    ReleaseSemaphore(sharedSemaphore, 1, nullptr);
}

void AcquireExclusive()
{
    for (unsigned i = 0; i < MAX_SHARED; i++) {
        WaitForSingleObject(sharedSemaphore, INFINITE);
    }
}

void ReleaseShared()
{
    ReleaseSemaphore(sharedSemaphore, MAX_SHARED, nullptr);
}

Since we are using Wait­For­Single­Object, we can also add a timeout, so that the caller can decide to abandon the operation if they can’t claim the lock.

bool AcquireSharedWithTimeout(DWORD timeout)
{
    return WaitForSingleObject(sharedSemaphore, timeout) == WAIT_OBJECT_0;
}

bool AcquireExclusiveWithTimeout(DWORD timeout)
{
    DWORD start = GetTickCount();
    for (unsigned i = 0; i < MAX_SHARED; i++) {
        DWORD elapsed = GetTickCount() - start;
        if (elapsed > timeout ||
            WaitForSingleObject(sharedSemaphore, timeout - elapsed) == WAIT_TIMEOUT)) {
            // Restore the tokens we already claimed.
            if (i > 0) {
                ReleaseSemaphore(sharedSemaphore, i, nullptr);
            }
            return false;
        }
    }
    return true;
}

Exclusive acquisition is tricky because we have to call Wait­For­Single­Object multiple times, with decreasing timeouts as time passes. If we run out of time, then we need to give back the tokens we had prematurely claimed.

There’s still a problem here. We’ll look at it next time.

The post Developing a cross-process reader/writer lock with limited readers, part 1: A semaphore appeared first on The Old New Thing.

Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

Introducing NVIDIA Nemotron 3 Nano Omni: Long-Context Multimodal Intelligence for Documents, Audio and Video Agents

1 Share
Read the whole story
alvinashcraft
36 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Onboarding Claude Code like a new developer: Lessons from 17 years of development

1 Share
Onboarding Claude Code like a new developer: Lessons from 17 years of development
Read the whole story
alvinashcraft
43 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

OpenAI models, Codex, and Managed Agents come to AWS

1 Share
OpenAI GPT models, Codex, and Managed Agents are now available on AWS, enabling enterprises to build secure AI in their AWS environments.
Read the whole story
alvinashcraft
49 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Warp is now open-source

1 Share
Today we are announcing a fundamental change in how we build Warp: the Warp client is now open-source, and the community can participate in building it using an agent-first workflow managed by Oz, our cloud agent orchestration platform. OpenAI is the founding sponsor of the new, open‑source Warp repository, and the new agentic management workflows are powered by GPT models. Open-sourcing with an agent-powered repo is our vision of how software will be built in the future. Humans managing agents...

Read the whole story
alvinashcraft
54 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

The virtuous loop of Open Agentic Development

1 Share
With today’s open-sourcing of Warp, our goal is to create a new way of building, where humans and agents collaborate in the open to ship better software, more quickly. We are creating a flywheel where a user’s idea becomes a real improvement to Warp—prototyped with an agent, refined and approved with our team, built and shipped by our agentic infrastructure, Oz, and verified together—so that each contribution makes the product better and brings more users into the fold. The more people that par...

Read the whole story
alvinashcraft
59 seconds ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories