Skip to content

Commit 75035b1

Browse files
dyxushuairockorager
authored andcommitted
Fix tryPush/tryPop semantics and DRY queue ops
1 parent 90cfa3c commit 75035b1

1 file changed

Lines changed: 26 additions & 28 deletions

File tree

src/queue.zig

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,7 @@ pub fn Queue(
3030
self.not_empty.wait(&self.mutex);
3131
}
3232
std.debug.assert(!self.isEmptyLH());
33-
if (self.isFullLH()) {
34-
// If we are full, wake up a push that might be
35-
// waiting here.
36-
self.not_full.signal();
37-
}
38-
39-
return self.popLH();
33+
return self.popAndSignalLH();
4034
}
4135

4236
/// Push an item into the queue. Blocks until an item has been
@@ -48,41 +42,27 @@ pub fn Queue(
4842
self.not_full.wait(&self.mutex);
4943
}
5044
std.debug.assert(!self.isFullLH());
51-
const was_empty = self.isEmptyLH();
52-
53-
self.buf[self.mask(self.write_index)] = item;
54-
self.write_index = self.mask2(self.write_index + 1);
55-
56-
// If we were empty, wake up a pop if it was waiting.
57-
if (was_empty) {
58-
self.not_empty.signal();
59-
}
45+
self.pushAndSignalLH(item);
6046
}
6147

6248
/// Push an item into the queue. Returns true when the item
6349
/// was successfully placed in the queue, false if the queue
6450
/// was full.
6551
pub fn tryPush(self: *Self, item: T) bool {
6652
self.mutex.lock();
67-
if (self.isFullLH()) {
68-
self.mutex.unlock();
69-
return false;
70-
}
71-
self.mutex.unlock();
72-
self.push(item);
53+
defer self.mutex.unlock();
54+
if (self.isFullLH()) return false;
55+
self.pushAndSignalLH(item);
7356
return true;
7457
}
7558

7659
/// Pop an item from the queue. Returns null when no item is
7760
/// available.
7861
pub fn tryPop(self: *Self) ?T {
7962
self.mutex.lock();
80-
if (self.isEmptyLH()) {
81-
self.mutex.unlock();
82-
return null;
83-
}
84-
self.mutex.unlock();
85-
return self.pop();
63+
defer self.mutex.unlock();
64+
if (self.isEmptyLH()) return null;
65+
return self.popAndSignalLH();
8666
}
8767

8868
/// Poll the queue. This call blocks until events are in the queue
@@ -150,6 +130,24 @@ pub fn Queue(
150130
return index % (2 * self.buf.len);
151131
}
152132

133+
fn pushAndSignalLH(self: *Self, item: T) void {
134+
const was_empty = self.isEmptyLH();
135+
self.buf[self.mask(self.write_index)] = item;
136+
self.write_index = self.mask2(self.write_index + 1);
137+
if (was_empty) {
138+
self.not_empty.signal();
139+
}
140+
}
141+
142+
fn popAndSignalLH(self: *Self) T {
143+
const was_full = self.isFullLH();
144+
const result = self.popLH();
145+
if (was_full) {
146+
self.not_full.signal();
147+
}
148+
return result;
149+
}
150+
153151
fn popLH(self: *Self) T {
154152
const result = self.buf[self.mask(self.read_index)];
155153
self.read_index = self.mask2(self.read_index + 1);

0 commit comments

Comments
 (0)