Skip to content

DefaultRwLock accumulates write-waiters, eventually fails to write lock #13163

Closed
@jumpnbrownweasel

Description

@jumpnbrownweasel

Zig Version

0.10.0-dev.4280+c3d67c5c4

Steps to Reproduce

Run the following test and expect it to run to completion (not hang).

test "RwLock" {
    var lock = std.Thread.RwLock.DefaultRwLock{};
    var i: usize = 0;
    while (i < std.math.maxInt(u32)) : (i += 1) {
        lock.lock();
        lock.unlock();
    }
    std.debug.print("\nAbout to lockShared...\n", .{});
    lock.lockShared();
}

Let it run for several minutes since it takes some time to run that many iterations, but eventually it will stop consuming CPU and hang waiting for a semaphore in the DefaultRwLock.lock method.

Expected Behavior

Prints the "About to lockShared..." message after several minutes and finishes running (no errors).

Actual Behavior

After several minutes it will stop consuming CPU and hang waiting for a semaphore in the DefaultRwLock.lock method. Although a large number (2^30 I believe) write locks must be taken before the problem occurs, it could definitely occur in a long running program.

Note that the Zig version doesn't matter. It fails on latest master, 0.9.0, and probably every other version, since the DefaultRwLock code has not changed and is neglecting to decrement the writes-waiting counter. I'll provide more info and a potential fix later in the issue.

The problem was originally found by @Curious Thing on Discord here:
https://discord.com/channels/605571803288698900/1028554539210645586

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorstandard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions