Skip to content

Commit 2f8ffdd

Browse files
refactor(downloads): remove some lifetime parameters to allow multi-thread installations
Co-authored-by: rami3l <[email protected]>
1 parent 5098f56 commit 2f8ffdd

File tree

13 files changed

+416
-332
lines changed

13 files changed

+416
-332
lines changed

src/config.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,19 @@ pub(crate) struct Cfg<'a> {
229229
pub toolchains_dir: PathBuf,
230230
pub update_hash_dir: PathBuf,
231231
pub download_dir: PathBuf,
232-
pub tmp_cx: temp::Context,
232+
pub tmp_cx: Arc<temp::Context>,
233233
pub toolchain_override: Option<ResolvableToolchainName>,
234234
pub env_override: Option<LocalToolchainName>,
235235
pub dist_root_url: String,
236-
pub notify_handler: Arc<dyn Fn(Notification<'_>)>,
236+
pub notify_handler: Arc<NotifyHandler>,
237237
pub current_dir: PathBuf,
238238
pub process: &'a Process,
239239
}
240240

241241
impl<'a> Cfg<'a> {
242242
pub(crate) fn from_env(
243243
current_dir: PathBuf,
244-
notify_handler: Arc<dyn Fn(Notification<'_>)>,
244+
notify_handler: Arc<NotifyHandler>,
245245
process: &'a Process,
246246
) -> Result<Self> {
247247
// Set up the rustup home directory
@@ -292,11 +292,11 @@ impl<'a> Cfg<'a> {
292292
let dist_root_server = dist_root_server(process)?;
293293

294294
let notify_clone = notify_handler.clone();
295-
let tmp_cx = temp::Context::new(
295+
let tmp_cx = Arc::new(temp::Context::new(
296296
rustup_dir.join("tmp"),
297297
dist_root_server.as_str(),
298-
Box::new(move |n| (notify_clone)(n)),
299-
);
298+
Arc::new(move |n| (notify_clone)(n)),
299+
));
300300
let dist_root = dist_root_server + "/dist";
301301

302302
let cfg = Self {
@@ -329,15 +329,15 @@ impl<'a> Cfg<'a> {
329329

330330
/// construct a download configuration
331331
pub(crate) fn download_cfg(
332-
&'a self,
333-
notify_handler: &'a dyn Fn(Notification<'_>),
334-
) -> DownloadCfg<'a> {
332+
&self,
333+
notify_handler: Arc<NotifyHandler>,
334+
) -> DownloadCfg {
335335
DownloadCfg {
336-
dist_root: &self.dist_root_url,
337-
tmp_cx: &self.tmp_cx,
338-
download_dir: &self.download_dir,
336+
dist_root: Arc::from(self.dist_root_url.clone()),
337+
tmp_cx: Arc::clone(&self.tmp_cx),
338+
download_dir: Arc::new(self.download_dir.clone()),
339339
notify_handler,
340-
process: self.process,
340+
process: Arc::new(self.process.clone()),
341341
}
342342
}
343343

src/dist/component/components.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl Components {
5555
Ok(None)
5656
}
5757
}
58-
fn write_version(&self, tx: &mut Transaction<'_>) -> Result<()> {
58+
fn write_version(&self, tx: &mut Transaction) -> Result<()> {
5959
tx.modify_file(self.prefix.rel_manifest_file(VERSION_FILE))?;
6060
utils::write_file(
6161
VERSION_FILE,
@@ -79,7 +79,7 @@ impl Components {
7979
})
8080
.collect())
8181
}
82-
pub(crate) fn add<'a>(&self, name: &str, tx: Transaction<'a>) -> ComponentBuilder<'a> {
82+
pub(crate) fn add(&self, name: &str, tx: Transaction) -> ComponentBuilder {
8383
ComponentBuilder {
8484
components: self.clone(),
8585
name: name.to_owned(),
@@ -96,14 +96,14 @@ impl Components {
9696
}
9797
}
9898

99-
pub(crate) struct ComponentBuilder<'a> {
99+
pub(crate) struct ComponentBuilder {
100100
components: Components,
101101
name: String,
102102
parts: Vec<ComponentPart>,
103-
tx: Transaction<'a>,
103+
tx: Transaction,
104104
}
105105

106-
impl<'a> ComponentBuilder<'a> {
106+
impl ComponentBuilder {
107107
pub(crate) fn copy_file(&mut self, path: PathBuf, src: &Path) -> Result<()> {
108108
self.parts.push(ComponentPart {
109109
kind: ComponentPartKind::File,
@@ -132,7 +132,7 @@ impl<'a> ComponentBuilder<'a> {
132132
});
133133
self.tx.move_dir(&self.name, path, src)
134134
}
135-
pub(crate) fn finish(mut self) -> Result<Transaction<'a>> {
135+
pub(crate) fn finish(mut self) -> Result<Transaction> {
136136
// Write component manifest
137137
let path = self.components.rel_component_manifest(&self.name);
138138
let abs_path = self.components.prefix.abs_path(&path);
@@ -255,18 +255,20 @@ impl Component {
255255
}
256256
Ok(result)
257257
}
258-
pub fn uninstall<'a>(
259-
&self,
260-
mut tx: Transaction<'a>,
261-
process: &Process,
262-
) -> Result<Transaction<'a>> {
258+
pub fn uninstall(&self, mut tx: Transaction, process: &Process) -> Result<Transaction> {
263259
// Update components file
264260
let path = self.components.rel_components_file();
265261
let abs_path = self.components.prefix.abs_path(&path);
266262
let temp = tx.temp().new_file()?;
267263
utils::filter_file("components", &abs_path, &temp, |l| l != self.name)?;
268264
tx.modify_file(path)?;
269-
utils::rename("components", &temp, &abs_path, tx.notify_handler(), process)?;
265+
utils::rename(
266+
"components",
267+
&temp,
268+
&abs_path,
269+
&*tx.notify_handler(),
270+
process,
271+
)?;
270272

271273
// TODO: If this is the last component remove the components file
272274
// and the version file.

src/dist/component/package.rs

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::fmt;
77
use std::io::{self, ErrorKind as IOErrorKind, Read};
88
use std::mem;
99
use std::path::{Path, PathBuf};
10+
use std::sync::Arc;
1011

1112
use anyhow::{Context, Result, anyhow, bail};
1213
use tar::EntryType;
@@ -27,13 +28,13 @@ pub(crate) const VERSION_FILE: &str = "rust-installer-version";
2728

2829
pub trait Package: fmt::Debug {
2930
fn contains(&self, component: &str, short_name: Option<&str>) -> bool;
30-
fn install<'a>(
31+
fn install(
3132
&self,
3233
target: &Components,
3334
component: &str,
3435
short_name: Option<&str>,
35-
tx: Transaction<'a>,
36-
) -> Result<Transaction<'a>>;
36+
tx: Transaction,
37+
) -> Result<Transaction>;
3738
fn components(&self) -> Vec<String>;
3839
}
3940

@@ -80,13 +81,13 @@ impl Package for DirectoryPackage {
8081
false
8182
}
8283
}
83-
fn install<'a>(
84+
fn install(
8485
&self,
8586
target: &Components,
8687
name: &str,
8788
short_name: Option<&str>,
88-
tx: Transaction<'a>,
89-
) -> Result<Transaction<'a>> {
89+
tx: Transaction,
90+
) -> Result<Transaction> {
9091
let actual_name = if self.components.contains(name) {
9192
name
9293
} else if let Some(n) = short_name {
@@ -138,11 +139,12 @@ impl Package for DirectoryPackage {
138139

139140
#[derive(Debug)]
140141
#[allow(dead_code)] // temp::Dir is held for drop.
141-
pub(crate) struct TarPackage<'a>(DirectoryPackage, temp::Dir<'a>);
142+
pub(crate) struct TarPackage(DirectoryPackage, temp::Dir);
142143

143-
impl<'a> TarPackage<'a> {
144-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
145-
let temp_dir = cx.tmp_cx.new_directory()?;
144+
impl TarPackage {
145+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
146+
let ctx = cx.tmp_cx.clone();
147+
let temp_dir = ctx.new_directory()?;
146148
let mut archive = tar::Archive::new(stream);
147149
// The rust-installer packages unpack to a directory called
148150
// $pkgname-$version-$target. Skip that directory when
@@ -161,7 +163,7 @@ impl<'a> TarPackage<'a> {
161163
fn unpack_ram(
162164
io_chunk_size: usize,
163165
effective_max_ram: Option<usize>,
164-
cx: &PackageContext<'_>,
166+
cx: &PackageContext,
165167
) -> usize {
166168
const RAM_ALLOWANCE_FOR_RUSTUP_AND_BUFFERS: usize = 200 * 1024 * 1024;
167169
let minimum_ram = io_chunk_size * 2;
@@ -199,7 +201,7 @@ fn unpack_ram(
199201
}
200202
}
201203
None => {
202-
if let Some(h) = cx.notify_handler {
204+
if let Some(h) = &cx.notify_handler {
203205
h(Notification::SetDefaultBufferSize(default_max_unpack_ram))
204206
}
205207
default_max_unpack_ram
@@ -285,21 +287,22 @@ enum DirStatus {
285287
fn unpack_without_first_dir<R: Read>(
286288
archive: &mut tar::Archive<R>,
287289
path: &Path,
288-
cx: &PackageContext<'_>,
290+
cx: &PackageContext,
289291
) -> Result<()> {
290292
let entries = archive.entries()?;
291293
let effective_max_ram = match effective_limits::memory_limit() {
292294
Ok(ram) => Some(ram as usize),
293295
Err(e) => {
294-
if let Some(h) = cx.notify_handler {
296+
if let Some(h) = &cx.notify_handler {
295297
h(Notification::Error(e.to_string()))
296298
}
297299
None
298300
}
299301
};
300302
let unpack_ram = unpack_ram(IO_CHUNK_SIZE, effective_max_ram, cx);
303+
let handler_ref = cx.notify_handler.as_ref().map(|h| h.as_ref());
301304
let mut io_executor: Box<dyn Executor> =
302-
get_executor(cx.notify_handler, unpack_ram, cx.process)?;
305+
get_executor(handler_ref, unpack_ram, &cx.process)?;
303306

304307
let mut directories: HashMap<PathBuf, DirStatus> = HashMap::new();
305308
// Path is presumed to exist. Call it a precondition.
@@ -528,17 +531,17 @@ fn unpack_without_first_dir<R: Read>(
528531
Ok(())
529532
}
530533

531-
impl Package for TarPackage<'_> {
534+
impl Package for TarPackage {
532535
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
533536
self.0.contains(component, short_name)
534537
}
535-
fn install<'b>(
538+
fn install(
536539
&self,
537540
target: &Components,
538541
component: &str,
539542
short_name: Option<&str>,
540-
tx: Transaction<'b>,
541-
) -> Result<Transaction<'b>> {
543+
tx: Transaction,
544+
) -> Result<Transaction> {
542545
self.0.install(target, component, short_name, tx)
543546
}
544547
fn components(&self) -> Vec<String> {
@@ -547,26 +550,26 @@ impl Package for TarPackage<'_> {
547550
}
548551

549552
#[derive(Debug)]
550-
pub(crate) struct TarGzPackage<'a>(TarPackage<'a>);
553+
pub(crate) struct TarGzPackage(TarPackage);
551554

552-
impl<'a> TarGzPackage<'a> {
553-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
555+
impl TarGzPackage {
556+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
554557
let stream = flate2::read::GzDecoder::new(stream);
555558
Ok(TarGzPackage(TarPackage::new(stream, cx)?))
556559
}
557560
}
558561

559-
impl Package for TarGzPackage<'_> {
562+
impl Package for TarGzPackage {
560563
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
561564
self.0.contains(component, short_name)
562565
}
563-
fn install<'b>(
566+
fn install(
564567
&self,
565568
target: &Components,
566569
component: &str,
567570
short_name: Option<&str>,
568-
tx: Transaction<'b>,
569-
) -> Result<Transaction<'b>> {
571+
tx: Transaction,
572+
) -> Result<Transaction> {
570573
self.0.install(target, component, short_name, tx)
571574
}
572575
fn components(&self) -> Vec<String> {
@@ -575,26 +578,26 @@ impl Package for TarGzPackage<'_> {
575578
}
576579

577580
#[derive(Debug)]
578-
pub(crate) struct TarXzPackage<'a>(TarPackage<'a>);
581+
pub(crate) struct TarXzPackage(TarPackage);
579582

580-
impl<'a> TarXzPackage<'a> {
581-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
583+
impl TarXzPackage {
584+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
582585
let stream = xz2::read::XzDecoder::new(stream);
583586
Ok(TarXzPackage(TarPackage::new(stream, cx)?))
584587
}
585588
}
586589

587-
impl Package for TarXzPackage<'_> {
590+
impl Package for TarXzPackage {
588591
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
589592
self.0.contains(component, short_name)
590593
}
591-
fn install<'b>(
594+
fn install(
592595
&self,
593596
target: &Components,
594597
component: &str,
595598
short_name: Option<&str>,
596-
tx: Transaction<'b>,
597-
) -> Result<Transaction<'b>> {
599+
tx: Transaction,
600+
) -> Result<Transaction> {
598601
self.0.install(target, component, short_name, tx)
599602
}
600603
fn components(&self) -> Vec<String> {
@@ -603,35 +606,35 @@ impl Package for TarXzPackage<'_> {
603606
}
604607

605608
#[derive(Debug)]
606-
pub(crate) struct TarZStdPackage<'a>(TarPackage<'a>);
609+
pub(crate) struct TarZStdPackage(TarPackage);
607610

608-
impl<'a> TarZStdPackage<'a> {
609-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
611+
impl TarZStdPackage {
612+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
610613
let stream = zstd::stream::read::Decoder::new(stream)?;
611614
Ok(TarZStdPackage(TarPackage::new(stream, cx)?))
612615
}
613616
}
614617

615-
impl Package for TarZStdPackage<'_> {
618+
impl Package for TarZStdPackage {
616619
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
617620
self.0.contains(component, short_name)
618621
}
619-
fn install<'b>(
622+
fn install(
620623
&self,
621624
target: &Components,
622625
component: &str,
623626
short_name: Option<&str>,
624-
tx: Transaction<'b>,
625-
) -> Result<Transaction<'b>> {
627+
tx: Transaction,
628+
) -> Result<Transaction> {
626629
self.0.install(target, component, short_name, tx)
627630
}
628631
fn components(&self) -> Vec<String> {
629632
self.0.components()
630633
}
631634
}
632635

633-
pub(crate) struct PackageContext<'a> {
634-
pub(crate) tmp_cx: &'a temp::Context,
635-
pub(crate) notify_handler: Option<&'a dyn Fn(Notification<'_>)>,
636-
pub(crate) process: &'a Process,
636+
pub(crate) struct PackageContext {
637+
pub(crate) tmp_cx: Arc<temp::Context>,
638+
pub(crate) notify_handler: Option<Arc<dyn Fn(Notification<'_>)>>,
639+
pub(crate) process: Arc<Process>,
637640
}

0 commit comments

Comments
 (0)