bson: make ObjectIdGen counter atomic for concurrent connections

This commit is contained in:
mongo-light
2026-08-02 10:29:16 +03:00
parent 4de42091a4
commit 62a4c4244c

View File

@@ -494,12 +494,16 @@ fn copy_values(arena: std.mem.Allocator, items: []const Value) std.mem.Allocator
pub const ObjectIdGen = struct { pub const ObjectIdGen = struct {
random_prefix: [5]u8, 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 { pub fn init(io: std.Io) ObjectIdGen {
var self: ObjectIdGen = undefined; var self: ObjectIdGen = undefined;
io.random(&self.random_prefix); io.random(&self.random_prefix);
self.counter = 0; self.counter = .init(0);
return self; return self;
} }
@@ -509,8 +513,8 @@ pub const ObjectIdGen = struct {
const secs: u32 = @truncate(@as(u64, @intCast(now.toSeconds()))); const secs: u32 = @truncate(@as(u64, @intCast(now.toSeconds())));
std.mem.writeInt(u32, oid[0..4], secs, .big); std.mem.writeInt(u32, oid[0..4], secs, .big);
@memcpy(oid[4..9], &self.random_prefix); @memcpy(oid[4..9], &self.random_prefix);
self.counter +%= 1; const n = self.counter.fetchAdd(1, .monotonic) +% 1;
std.mem.writeInt(u24, oid[9..12], @truncate(self.counter), .big); std.mem.writeInt(u24, oid[9..12], @truncate(n), .big);
return oid; return oid;
} }
}; };