Moved CalculateCabbingThreadCount() to BindDatabaseCommand because we need the capped value in both CreateCabinetsCommand and UpdateFileFacadesCommand.
Fixed bug in capping the thread count between 1 and processor count times 2. The "-ct 1000000" value was wrongly passed thru in the test CabinetFilesSequencedCorrectly Added ThreadCount to UpdateFileFacadesCommand
Martin Broholm Andersen committed
Aug 31, 2024 at 12:23 UTC
fb769130df465bca45c520c27baf85343881ef14
3 files changed
+35
-31
src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+28
-3
@@ -105,6 +105,29 @@ namespace WixToolset.Core.WindowsInstaller.Bind
105
106
private CancellationToken CancellationToken { get; }
107
108
+ private int CalculateCabbingThreadCount()
109
+ {
110
+ var processorCount = Environment.ProcessorCount;
111
+
112
+ // If the number of processors is invalid, default to a single processor.
113
+ if (processorCount == 0)
114
+ {
115
+ processorCount = 1;
116
+
117
+ this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
118
+ }
119
+
120
+ // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it.
121
+ if (0 < this.CabbingThreadCount && this.CabbingThreadCount < processorCount * 2)
122
+ {
123
+ processorCount = this.CabbingThreadCount;
124
+ }
125
+
126
+ this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString()));
127
+
128
+ return processorCount;
129
+ }
130
+
131
public IBindResult Execute()
132
{
133
if (!this.Intermediate.HasLevel(Data.IntermediateLevels.Linked) || !this.Intermediate.HasLevel(Data.IntermediateLevels.Resolved))
@@ -123,6 +146,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
146
147
var containsMergeModules = false;
148
149
+ int calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
150
+
151
// Load standard tables, authored custom tables, and extension custom tables.
152
TableDefinitionCollection tableDefinitions;
153
{
@@ -280,7 +305,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
305
306
// Gather information about files that do not come from merge modules.
307
{
283
- var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true, this.CancellationToken);
308
+ var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true, this.CancellationToken, calculatedCabbingThreadCount);
309
command.Execute();
310
}
311
@@ -324,7 +349,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
349
{
350
var updatedFacades = reresolvedFiles.Select(f => allFileFacades.First(ff => ff.Id == f.Id?.Id));
351
327
- var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false, this.CancellationToken);
352
+ var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false, this.CancellationToken, calculatedCabbingThreadCount);
353
command.Execute();
354
}
355
}
@@ -442,7 +467,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
467
{
468
this.Messaging.Write(VerboseMessages.CreatingCabinetFiles());
469
445
- var command = new CreateCabinetsCommand(this.ServiceProvider, this.Messaging, this.WindowsInstallerBackendHelper, this.BackendExtensions, section, this.CabCachePath, this.CabbingThreadCount, this.OutputPath, this.IntermediateFolder, this.DefaultCompressionLevel, compressed, modularizationSuffix, filesByCabinetMedia, data, tableDefinitions, this.ResolveMedia);
470
+ var command = new CreateCabinetsCommand(this.ServiceProvider, this.Messaging, this.WindowsInstallerBackendHelper, this.BackendExtensions, section, this.CabCachePath, calculatedCabbingThreadCount, this.OutputPath, this.IntermediateFolder, this.DefaultCompressionLevel, compressed, modularizationSuffix, filesByCabinetMedia, data, tableDefinitions, this.ResolveMedia);
471
command.Execute();
472
473
fileTransfers.AddRange(command.FileTransfers);
src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+1
-26
@@ -83,11 +83,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83
84
public void Execute()
85
{
86
- var calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
87
-
86
this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize);
87
90
- var cabinetBuilder = new CabinetBuilder(this.Messaging, calculatedCabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
88
+ var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
89
90
var hashesByFileId = this.Section.Symbols.OfType<MsiFileHashSymbol>().ToDictionary(s => s.Id.Id);
91
@@ -122,29 +120,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
120
this.UpdateMediaWithSpannedCabinets(cabinetBuilder.CompletedCabinets);
121
}
122
125
- private int CalculateCabbingThreadCount()
126
- {
127
- var processorCount = Environment.ProcessorCount;
128
-
129
- // If the number of processors is invalid, default to a single processor.
130
- if (processorCount == 0)
131
- {
132
- processorCount = 1;
133
-
134
- this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
135
- }
136
-
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
-
123
private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<IFileFacade> fileFacades, Dictionary<string, MsiFileHashSymbol> hashesByFileId)
124
{
125
CabinetWorkItem cabinetWorkItem = null;
src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+6
-2
@@ -22,7 +22,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
22
/// </summary>
23
internal class UpdateFileFacadesCommand
24
{
25
- public UpdateFileFacadesCommand(IMessaging messaging, IFileSystem fileSystem, IntermediateSection section, IEnumerable<IFileFacade> allFileFacades, IEnumerable<IFileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash, CancellationToken cancellationToken)
25
+ public UpdateFileFacadesCommand(IMessaging messaging, IFileSystem fileSystem, IntermediateSection section, IEnumerable<IFileFacade> allFileFacades, IEnumerable<IFileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash, CancellationToken cancellationToken, int threadCount)
26
{
27
this.Messaging = messaging;
28
this.FileSystem = fileSystem;
@@ -32,6 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32
this.VariableCache = variableCache;
33
this.OverwriteHash = overwriteHash;
34
this.CancellationToken = cancellationToken;
35
+ this.ThreadCount = threadCount;
36
}
37
38
private IMessaging Messaging { get; }
@@ -50,6 +51,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51
52
private CancellationToken CancellationToken { get; }
53
54
+ private int ThreadCount { get; }
55
+
56
public void Execute()
57
{
58
try
@@ -74,7 +77,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
77
78
Parallel.ForEach(facades,
79
new ParallelOptions{
77
- CancellationToken = this.CancellationToken
80
+ CancellationToken = this.CancellationToken,
81
+ MaxDegreeOfParallelism = this.ThreadCount
82
},
83
() =>
84
{