bson: make ObjectIdGen counter atomic for concurrent connections
This commit is contained in:
12
src/bson.zig
12
src/bson.zig
@@ -494,12 +494,16 @@ fn copy_values(arena: std.mem.Allocator, items: []const Value) std.mem.Allocator
|
||||
|
||||
pub const ObjectIdGen = struct {
|
||||
random_prefix: [5]u8,
|
||||
counter: u32,
|
||||
// Atomic so concurrent connections (e.g. two hellos, or a hello racing
|
||||
// an insert) can share one generator without a data race. The counter
|
||||
// only needs uniqueness within a second + random prefix, so monotonic
|
||||
// fetchAdd is fine.
|
||||
counter: std.atomic.Value(u32),
|
||||
|
||||
pub fn init(io: std.Io) ObjectIdGen {
|
||||
var self: ObjectIdGen = undefined;
|
||||
io.random(&self.random_prefix);
|
||||
self.counter = 0;
|
||||
self.counter = .init(0);
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -509,8 +513,8 @@ pub const ObjectIdGen = struct {
|
||||
const secs: u32 = @truncate(@as(u64, @intCast(now.toSeconds())));
|
||||
std.mem.writeInt(u32, oid[0..4], secs, .big);
|
||||
@memcpy(oid[4..9], &self.random_prefix);
|
||||
self.counter +%= 1;
|
||||
std.mem.writeInt(u24, oid[9..12], @truncate(self.counter), .big);
|
||||
const n = self.counter.fetchAdd(1, .monotonic) +% 1;
|
||||
std.mem.writeInt(u24, oid[9..12], @truncate(n), .big);
|
||||
return oid;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user