Skip to content

Commit 750c216

Browse files
refactor(downloads): remove some lifetime parameters to allow multi-thread installations
Co-authored-by: rami3l <[email protected]>
1 parent 4ed8bb2 commit 750c216

File tree

13 files changed

+422
-335
lines changed

13 files changed

+422
-335
lines changed

src/config.rs

Lines changed: 11 additions & 14 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 {
@@ -328,16 +328,13 @@ impl<'a> Cfg<'a> {
328328
}
329329

330330
/// construct a download configuration
331-
pub(crate) fn download_cfg(
332-
&'a self,
333-
notify_handler: &'a dyn Fn(Notification<'_>),
334-
) -> DownloadCfg<'a> {
331+
pub(crate) fn download_cfg(&self, notify_handler: Arc<NotifyHandler>) -> DownloadCfg {
335332
DownloadCfg {
336-
dist_root: &self.dist_root_url,
337-
tmp_cx: &self.tmp_cx,
338-
download_dir: &self.download_dir,
333+
dist_root: Arc::from(self.dist_root_url.clone()),
334+
tmp_cx: Arc::clone(&self.tmp_cx),
335+
download_dir: Arc::new(self.download_dir.clone()),
339336
notify_handler,
340-
process: self.process,
337+
process: Arc::new(self.process.clone()),
341338
}
342339
}
343340

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 & 45 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,21 @@ 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);
301-
let mut io_executor: Box<dyn Executor> =
302-
get_executor(cx.notify_handler, unpack_ram, cx.process)?;
303+
let handler_ref = cx.notify_handler.as_ref().map(|h| h.as_ref());
304+
let mut io_executor: Box<dyn Executor> = get_executor(handler_ref, unpack_ram, &cx.process)?;
303305

304306
let mut directories: HashMap<PathBuf, DirStatus> = HashMap::new();
305307
// Path is presumed to exist. Call it a precondition.
@@ -528,17 +530,17 @@ fn unpack_without_first_dir<R: Read>(
528530
Ok(())
529531
}
530532

531-
impl Package for TarPackage<'_> {
533+
impl Package for TarPackage {
532534
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
533535
self.0.contains(component, short_name)
534536
}
535-
fn install<'b>(
537+
fn install(
536538
&self,
537539
target: &Components,
538540
component: &str,
539541
short_name: Option<&str>,
540-
tx: Transaction<'b>,
541-
) -> Result<Transaction<'b>> {
542+
tx: Transaction,
543+
) -> Result<Transaction> {
542544
self.0.install(target, component, short_name, tx)
543545
}
544546
fn components(&self) -> Vec<String> {
@@ -547,26 +549,26 @@ impl Package for TarPackage<'_> {
547549
}
548550

549551
#[derive(Debug)]
550-
pub(crate) struct TarGzPackage<'a>(TarPackage<'a>);
552+
pub(crate) struct TarGzPackage(TarPackage);
551553

552-
impl<'a> TarGzPackage<'a> {
553-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
554+
impl TarGzPackage {
555+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
554556
let stream = flate2::read::GzDecoder::new(stream);
555557
Ok(TarGzPackage(TarPackage::new(stream, cx)?))
556558
}
557559
}
558560

559-
impl Package for TarGzPackage<'_> {
561+
impl Package for TarGzPackage {
560562
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
561563
self.0.contains(component, short_name)
562564
}
563-
fn install<'b>(
565+
fn install(
564566
&self,
565567
target: &Components,
566568
component: &str,
567569
short_name: Option<&str>,
568-
tx: Transaction<'b>,
569-
) -> Result<Transaction<'b>> {
570+
tx: Transaction,
571+
) -> Result<Transaction> {
570572
self.0.install(target, component, short_name, tx)
571573
}
572574
fn components(&self) -> Vec<String> {
@@ -575,26 +577,26 @@ impl Package for TarGzPackage<'_> {
575577
}
576578

577579
#[derive(Debug)]
578-
pub(crate) struct TarXzPackage<'a>(TarPackage<'a>);
580+
pub(crate) struct TarXzPackage(TarPackage);
579581

580-
impl<'a> TarXzPackage<'a> {
581-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
582+
impl TarXzPackage {
583+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
582584
let stream = xz2::read::XzDecoder::new(stream);
583585
Ok(TarXzPackage(TarPackage::new(stream, cx)?))
584586
}
585587
}
586588

587-
impl Package for TarXzPackage<'_> {
589+
impl Package for TarXzPackage {
588590
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
589591
self.0.contains(component, short_name)
590592
}
591-
fn install<'b>(
593+
fn install(
592594
&self,
593595
target: &Components,
594596
component: &str,
595597
short_name: Option<&str>,
596-
tx: Transaction<'b>,
597-
) -> Result<Transaction<'b>> {
598+
tx: Transaction,
599+
) -> Result<Transaction> {
598600
self.0.install(target, component, short_name, tx)
599601
}
600602
fn components(&self) -> Vec<String> {
@@ -603,35 +605,35 @@ impl Package for TarXzPackage<'_> {
603605
}
604606

605607
#[derive(Debug)]
606-
pub(crate) struct TarZStdPackage<'a>(TarPackage<'a>);
608+
pub(crate) struct TarZStdPackage(TarPackage);
607609

608-
impl<'a> TarZStdPackage<'a> {
609-
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext<'a>) -> Result<Self> {
610+
impl TarZStdPackage {
611+
pub(crate) fn new<R: Read>(stream: R, cx: &PackageContext) -> Result<Self> {
610612
let stream = zstd::stream::read::Decoder::new(stream)?;
611613
Ok(TarZStdPackage(TarPackage::new(stream, cx)?))
612614
}
613615
}
614616

615-
impl Package for TarZStdPackage<'_> {
617+
impl Package for TarZStdPackage {
616618
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
617619
self.0.contains(component, short_name)
618620
}
619-
fn install<'b>(
621+
fn install(
620622
&self,
621623
target: &Components,
622624
component: &str,
623625
short_name: Option<&str>,
624-
tx: Transaction<'b>,
625-
) -> Result<Transaction<'b>> {
626+
tx: Transaction,
627+
) -> Result<Transaction> {
626628
self.0.install(target, component, short_name, tx)
627629
}
628630
fn components(&self) -> Vec<String> {
629631
self.0.components()
630632
}
631633
}
632634

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,
635+
pub(crate) struct PackageContext {
636+
pub(crate) tmp_cx: Arc<temp::Context>,
637+
pub(crate) notify_handler: Option<Arc<dyn Fn(Notification<'_>)>>,
638+
pub(crate) process: Arc<Process>,
637639
}

0 commit comments

Comments
 (0)