Implement cab thread count
Closes 6978
Rob Mensching committed
Nov 6, 2022 at 19:29 UTC
d5673c535ea6ce81e87e891746ac14088aee0184
3 files changed
+41
-16
src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+16
-13
@@ -83,17 +83,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83
84
public void Execute()
85
{
86
- // If the cabbing thread count wasn't provided, default the number of cabbing threads to the number of processors.
87
- if (this.CabbingThreadCount <= 0)
88
- {
89
- this.CabbingThreadCount = this.CalculateCabbingThreadCount();
90
-
91
- this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
92
- }
86
+ var calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
87
88
this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize);
89
96
- var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
90
+ var cabinetBuilder = new CabinetBuilder(this.Messaging, calculatedCabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
91
92
var hashesByFileId = this.Section.Symbols.OfType<MsiFileHashSymbol>().ToDictionary(s => s.Id.Id);
93
@@ -130,16 +124,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
124
125
private int CalculateCabbingThreadCount()
126
{
133
- var cabbingThreadCount = Environment.ProcessorCount;
127
+ var processorCount = Environment.ProcessorCount;
128
135
- if (cabbingThreadCount <= 0)
129
+ // If the number of processors is invalid, default to a single processor.
130
+ if (processorCount == 0)
131
{
137
- cabbingThreadCount = 1; // reset to 1 when the environment variable is invalid.
132
+ processorCount = 1;
133
139
- this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), cabbingThreadCount.ToString()));
134
+ this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
135
}
136
142
- return cabbingThreadCount;
137
+ // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it.
138
+ if (this.CabbingThreadCount > 0 && processorCount < this.CabbingThreadCount * 2)
139
+ {
140
+ processorCount = this.CabbingThreadCount;
141
+ }
142
+
143
+ this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString()));
144
+
145
+ return processorCount;
146
}
147
148
private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<IFileFacade> fileFacades, Dictionary<string, MsiFileHashSymbol> hashesByFileId)
src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
+24
-3
@@ -52,6 +52,7 @@ namespace WixToolset.Core.CommandLine
52
new CommandLineHelpSwitch("-bindpath:target", "-bt", "Bind path to search for target package's content files. Only used when building a patch."),
53
new CommandLineHelpSwitch("-bindpath:update", "-bu", "Bind path to search for update package's content files. Only used when building a patch."),
54
new CommandLineHelpSwitch("-cabcache", "-cc", "Set a folder to cache cabinets across builds."),
55
+ new CommandLineHelpSwitch("-cabthreads", "-ct", "Override the number of threads used to create cabinets."),
56
new CommandLineHelpSwitch("-culture", "Adds a culture to filter localization files."),
57
new CommandLineHelpSwitch("-define", "-d", "Sets a preprocessor variable."),
58
new CommandLineHelpSwitch("-defaultcompressionlevel", "-dcl", "Default compression level; see Compression levels below."),
@@ -147,7 +148,7 @@ namespace WixToolset.Core.CommandLine
148
{
149
using (new IntermediateFieldContext("wix.bind"))
150
{
150
- this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, inputsOutputs, cancellationToken);
151
+ this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.CabbingThreadCount, this.commandLine.BindPaths, inputsOutputs, cancellationToken);
152
}
153
}
154
}
@@ -265,7 +266,7 @@ namespace WixToolset.Core.CommandLine
266
return linker.Link(context);
267
}
268
268
- private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken)
269
+ private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, int cabbingThreadCount, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken)
270
{
271
IResolveResult resolveResult;
272
{
@@ -295,7 +296,7 @@ namespace WixToolset.Core.CommandLine
296
{
297
var context = this.ServiceProvider.GetService<IBindContext>();
298
context.BindPaths = bindPaths;
298
- //context.CabbingThreadCount = this.CabbingThreadCount;
299
+ context.CabbingThreadCount = cabbingThreadCount;
300
context.CabCachePath = cabCachePath;
301
context.ResolvedCodepage = resolveResult.Codepage;
302
context.ResolvedSummaryInformationCodepage = resolveResult.SummaryInformationCodepage;
@@ -467,6 +468,8 @@ namespace WixToolset.Core.CommandLine
468
469
public string CabCachePath { get; private set; }
470
471
+ public int CabbingThreadCount { get; private set; }
472
+
473
public List<string> Cultures { get; } = new List<string>();
474
475
public List<string> Defines { get; } = new List<string>();
@@ -566,6 +569,24 @@ namespace WixToolset.Core.CommandLine
569
this.CabCachePath = parser.GetNextArgumentOrError(arg);
570
return true;
571
572
+ case "ct":
573
+ case "cabthreads":
574
+ {
575
+ var value = parser.GetNextArgumentOrError(arg);
576
+ if (Int32.TryParse(value, out var cabbingThreads))
577
+ {
578
+ this.CabbingThreadCount = cabbingThreads;
579
+ }
580
+ else if (!String.IsNullOrEmpty(value))
581
+ {
582
+ var processorCount = Environment.ProcessorCount == 0 ? 1 : Environment.ProcessorCount;
583
+ var range = Enumerable.Range(1, processorCount * 2).Select(i => i.ToString());
584
+ parser.ReportErrorArgument(arg, ErrorMessages.IllegalCommandLineArgumentValue(arg, value, range));
585
+ }
586
+
587
+ return true;
588
+ }
589
+
590
case "culture":
591
parser.GetNextArgumentOrError(arg, this.Cultures);
592
return true;
src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs
+1
@@ -28,6 +28,7 @@ namespace WixToolsetTest.CoreIntegration
28
"build",
29
Path.Combine(folder, "Package.wxs"),
30
Path.Combine(folder, "PackageComponents.wxs"),
31
+ "-ct", "1000000",
32
"-d", "MediaTemplateCompressionLevel",
33
"-loc", Path.Combine(folder, "Package.en-us.wxl"),
34
"-bindpath", Path.Combine(folder, "data"),