protected virtual SoftwareInfo DoGetSoftware(IEnumerable <IProductBinarySoftwareDetector> detectors, byte[] prefix, byte[] inBuffer, IProgress <double> progress, CancellationToken token) { var processorCount = Environment.ProcessorCount; var count = MaxThreads > 0 && MaxThreads < processorCount ? MaxThreads : processorCount; var offsets = GetOffsets(); var watch = new Stopwatch(); watch.Start(); var workers = new BinarySoftwareDetectorWorker[count]; for (var i = 0; i < count; i++) { workers[i] = new BinarySoftwareDetectorWorker(detectors, BinaryDecoder, prefix, inBuffer, i * offsets.Length / count, (i + 1) * offsets.Length / count, offsets); } var progressState = new ProgressState(offsets.Length, progress); var software = GetSoftware(workers, offsets.Length, progressState, token); watch.Stop(); Logger.LogDebug("Detecting software completed in {0}", watch.Elapsed); progressState.Reset(); return(software); }
public SoftwareInfo GetSoftware(ProgressState progress, CancellationToken token) { if (offsets == null) { return(PlainGetSoftware()); } for (var index = 0; index < offsets.Length; index++) { if (progress.IsCompleted) { return(null); } token.ThrowIfCancellationRequested(); var software = GetSoftware(offsets[index]); if (software != null) { progress.SetCompleted(); return(software); } progress.Update(); } return(null); }
private SoftwareInfo GetSoftware(BinarySoftwareDetectorWorker[] workers, int offsetCount, ProgressState progress, CancellationToken token) { var workerCount = workers.Length; if (workerCount == 1) { Logger.LogDebug("Detecting software in a single thread from {0} offsets", offsetCount); return(workers[0].GetSoftware(progress, token)); } Logger.LogDebug("Detecting software in {0} threads from {1} offsets", workerCount, offsetCount); var threads = new Thread[workerCount]; var results = new SoftwareInfo[workerCount]; for (var j = 0; j < threads.Length; j++) { var i = j; threads[i] = new Thread(() => results[i] = workers[i].GetSoftware(progress, token)); } foreach (var thread in threads) { thread.Start(); } foreach (var thread in threads) { thread.Join(); } return(results .FirstOrDefault(s => s != null)); }