a modern tui library written in zig

Fix tryPush/tryPop semantics and DRY queue ops

authored by john xu and committed by rockorager.dev 75035b16 90cfa3c9

Changed files
+26 -28
src
+26 -28
src/queue.zig
··· 30 30 self.not_empty.wait(&self.mutex); 31 31 } 32 32 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(); 40 34 } 41 35 42 36 /// Push an item into the queue. Blocks until an item has been ··· 48 42 self.not_full.wait(&self.mutex); 49 43 } 50 44 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); 60 46 } 61 47 62 48 /// Push an item into the queue. Returns true when the item ··· 64 50 /// was full. 65 51 pub fn tryPush(self: *Self, item: T) bool { 66 52 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); 73 56 return true; 74 57 } 75 58 ··· 77 60 /// available. 78 61 pub fn tryPop(self: *Self) ?T { 79 62 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(); 86 66 } 87 67 88 68 /// Poll the queue. This call blocks until events are in the queue ··· 148 128 /// Returns `index` modulo twice the length of the backing slice. 149 129 fn mask2(self: Self, index: usize) usize { 150 130 return index % (2 * self.buf.len); 131 + } 132 + 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; 151 149 } 152 150 153 151 fn popLH(self: *Self) T {