authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-09 18:06:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:14-07:00
log7db74009db4a4dc820e3e32c805ab7e29394205b
tree20be711f98fc5aa0214fa6dc7a4cc600ad8414b7
parent7106a91b097c5ac0feb13f328bec5e6788f8c8ef

std.Progress.Node: add a setName method

This can be used to update an existing node's label rather than indicate that more things have been accomplished.

1 files changed, 26 insertions(+), 7 deletions(-)

lib/std/Progress.zig+26-7
...@@ -126,6 +126,21 @@ pub const Node = struct {...@@ -126,6 +126,21 @@ pub const Node = struct {
126 }126 }
127 }127 }
128128
129 /// Thread-safe.
130 pub fn setName(self: *Node, name: []const u8) void {
131 const progress = self.context;
132 progress.update_mutex.lock();
133 defer progress.update_mutex.unlock();
134 self.name = name;
135 if (self.parent) |parent| {
136 @atomicStore(?*Node, &parent.recently_updated_child, self, .Release);
137 if (parent.parent) |grand_parent| {
138 @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .Release);
139 }
140 if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer);
141 }
142 }
143
129 /// Thread-safe. 0 means unknown.144 /// Thread-safe. 0 means unknown.
130 pub fn setEstimatedTotalItems(self: *Node, count: usize) void {145 pub fn setEstimatedTotalItems(self: *Node, count: usize) void {
131 @atomicStore(usize, &self.unprotected_estimated_total_items, count, .Monotonic);146 @atomicStore(usize, &self.unprotected_estimated_total_items, count, .Monotonic);
...@@ -174,16 +189,20 @@ pub fn maybeRefresh(self: *Progress) void {...@@ -174,16 +189,20 @@ pub fn maybeRefresh(self: *Progress) void {
174 if (self.timer) |*timer| {189 if (self.timer) |*timer| {
175 if (!self.update_mutex.tryLock()) return;190 if (!self.update_mutex.tryLock()) return;
176 defer self.update_mutex.unlock();191 defer self.update_mutex.unlock();
177 const now = timer.read();192 maybeRefreshWithHeldLock(self, timer);
178 if (now < self.initial_delay_ns) return;
179 // TODO I have observed this to happen sometimes. I think we need to follow Rust's
180 // lead and guarantee monotonically increasing times in the std lib itself.
181 if (now < self.prev_refresh_timestamp) return;
182 if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return;
183 return self.refreshWithHeldLock();
184 }193 }
185}194}
186195
196fn maybeRefreshWithHeldLock(self: *Progress, timer: *std.time.Timer) void {
197 const now = timer.read();
198 if (now < self.initial_delay_ns) return;
199 // TODO I have observed this to happen sometimes. I think we need to follow Rust's
200 // lead and guarantee monotonically increasing times in the std lib itself.
201 if (now < self.prev_refresh_timestamp) return;
202 if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return;
203 return self.refreshWithHeldLock();
204}
205
187/// Updates the terminal and resets `self.next_refresh_timestamp`. Thread-safe.206/// Updates the terminal and resets `self.next_refresh_timestamp`. Thread-safe.
188pub fn refresh(self: *Progress) void {207pub fn refresh(self: *Progress) void {
189 if (!self.update_mutex.tryLock()) return;208 if (!self.update_mutex.tryLock()) return;