...

Text file src/github.com/alecthomas/chroma/lexers/testdata/zig.actual

Documentation: github.com/alecthomas/chroma/lexers/testdata

     1const std = @import("std.zig");
     2const builtin = std.builtin;
     3const testing = std.testing;
     4
     5pub fn once(comptime f: fn () void) Once(f) {
     6    return Once(f){};
     7}
     8
     9/// An object that executes the function `f` just once.
    10pub fn Once(comptime f: fn () void) type {
    11    return struct {
    12        done: bool = false,
    13        mutex: std.Mutex = std.Mutex.init(),
    14
    15        /// Call the function `f`.
    16        /// If `call` is invoked multiple times `f` will be executed only the
    17        /// first time.
    18        /// The invocations are thread-safe.
    19        pub fn call(self: *@This()) void {
    20            if (@atomicLoad(bool, &self.done, .Acquire))
    21                return;
    22
    23            return self.callSlow();
    24        }
    25
    26        fn callSlow(self: *@This()) void {
    27            @setCold(true);
    28
    29            const T = self.mutex.acquire();
    30            defer T.release();
    31
    32            // The first thread to acquire the mutex gets to run the initializer
    33            if (!self.done) {
    34                f();
    35                @atomicStore(bool, &self.done, true, .Release);
    36            }
    37        }
    38    };
    39}
    40
    41var global_number: i32 = 0;
    42var global_once = once(incr);
    43
    44fn incr() void {
    45    global_number += 1;
    46}
    47
    48test "Once executes its function just once" {
    49    if (builtin.single_threaded) {
    50        global_once.call();
    51        global_once.call();
    52    } else {
    53        var threads: [10]*std.Thread = undefined;
    54        defer for (threads) |handle| handle.wait();
    55
    56        for (threads) |*handle| {
    57            handle.* = try std.Thread.spawn(@as(u8, 0), struct {
    58                fn thread_fn(x: u8) void {
    59                    global_once.call();
    60                }
    61            }.thread_fn);
    62        }
    63    }
    64
    65    testing.expectEqual(@as(i32, 1), global_number);
    66}

View as plain text