@@ -12,6 +12,8 @@ const CommonPaths = paths.CommonPaths;
1212const http = std .http ;
1313const Sha256 = std .crypto .hash .sha2 .Sha256 ;
1414const release_name = common .release_name ;
15+ const AtomicOrder = std .builtin .AtomicOrder ;
16+ const time = std .time ;
1517
1618const default_os = builtin .target .os .tag ;
1719const default_arch = builtin .target .cpu .arch ;
@@ -115,35 +117,49 @@ pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, t
115117 try req .? .wait ();
116118 var reader = req .? .reader ();
117119
118- var progress_bar : [150 ]u8 = ("░" ** 50 ).* ;
119- var stderr_writer = std .io .getStdErr ().writer ();
120120 var buff : [1024 ]u8 = undefined ;
121- var bars : u8 = 0 ;
122121
123122 // Convert everything into f64 for less typing in calculating % download and download speed
124- var dlnow : f64 = @floatFromInt ( tarball_size );
123+ var dlnow = std . atomic . Value ( f64 ). init ( 0 );
125124 const total_size_double : f64 = @floatFromInt (total_size );
126125
126+ const progress_thread = try std .Thread .spawn (.{}, download_progress_bar , .{ & dlnow , @as (f64 , @floatFromInt (tarball_size )), total_size_double });
127127 while (true ) {
128128 const len = try reader .read (& buff );
129129 if (len == 0 ) {
130130 break ;
131131 }
132132 _ = try tb_writer .write (buff [0.. len ]);
133133
134- dlnow += @floatFromInt (len );
135- const pcnt_complete : u8 = @intFromFloat (dlnow * 100 / total_size_double );
136- var timer = try std .time .Timer .start ();
134+ _ = dlnow .fetchAdd (@floatFromInt (len ), AtomicOrder .monotonic );
135+ }
136+ progress_thread .join ();
137+ try tb_writer .flush ();
138+ }
139+
140+ pub fn download_progress_bar (dlnow : * std .atomic .Value (f64 ), tarball_size : f64 , total_size : f64 ) ! void {
141+ var stderr_writer = std .io .getStdErr ().writer ();
142+ var progress_bar : [150 ]u8 = ("░" ** 50 ).* ;
143+ var bars : u8 = 0 ;
144+ var timer = try time .Timer .start ();
145+ var downloaded = dlnow .load (AtomicOrder .monotonic );
146+
147+ while (true ) {
148+ const pcnt_complete : u8 = @intFromFloat ((downloaded + tarball_size ) * 100 / total_size );
137149 const newbars : u8 = pcnt_complete / 2 ;
138150 for (bars .. newbars ) | i | {
139151 std .mem .copyForwards (u8 , progress_bar [i * 3 .. i * 3 + 3 ], "█" );
140152 }
141153 bars = newbars ;
142- const dlspeed = dlnow / 1024 * 8 / @as (f64 , @floatFromInt (timer .read ()));
143- try stderr_writer .print ("\r \t \x1b [33m{s}\x1b [0m{s} {d}% {d:.1}kb/s" , .{ progress_bar [0 .. newbars * 3 ], progress_bar [newbars * 3 .. ], pcnt_complete , dlspeed });
154+ const speed = downloaded / 1024 / @as (f64 , @floatFromInt (timer .read () / time .ns_per_s ));
155+ try stderr_writer .print ("\r \t \x1b [33m{s}\x1b [0m{s} {d}% {d:.1}KB/s" , .{ progress_bar [0 .. newbars * 3 ], progress_bar [newbars * 3 .. ], pcnt_complete , speed });
156+
157+ if (downloaded + tarball_size == total_size ) break ;
158+
159+ std .time .sleep (500 * time .ns_per_ms );
160+ downloaded = dlnow .load (AtomicOrder .monotonic );
144161 }
145162 try stderr_writer .print ("\n " , .{});
146- try tb_writer .flush ();
147163}
148164
149165pub fn get_json_dslist (client : * Client ) anyerror ! JsonResponse {
0 commit comments