add a GC.Collect() call to workaround a .net slow-GC problem, and fix an old bug related to firmware scans occurring several times actually every time you think it should happen once, which probably wasn't helping things

This commit is contained in:
zeromus 2014-11-12 00:04:08 +00:00
parent f5d9de5178
commit 4d5b25600e
2 changed files with 127 additions and 110 deletions

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -36,8 +37,10 @@ namespace BizHawk.Client.Common
return Resolve(FirmwareDatabase.LookupFirmwareRecord(sysId, firmwareId));
}
public ResolutionInfo Resolve(FirmwareDatabase.FirmwareRecord record)
public ResolutionInfo Resolve(FirmwareDatabase.FirmwareRecord record, bool forbidScan = false)
{
//purpose of forbidScan: sometimes this is called from a loop in Scan(). we dont want to repeatedly DoScanAndResolve in that case, its already been done.
bool first = true;
RETRY:
@ -49,7 +52,7 @@ namespace BizHawk.Client.Common
// NOTE: this could result in bad performance in some cases if the scanning happens repeatedly..
if (resolved == null && first)
{
DoScanAndResolve();
if(!forbidScan) DoScanAndResolve();
first = false;
goto RETRY;
}
@ -65,9 +68,15 @@ namespace BizHawk.Client.Common
return resolved.FilePath;
}
public class RealFirmwareReader
public class RealFirmwareReader : IDisposable
{
byte[] buffer = new byte[0];
System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
public void Dispose()
{
sha1.Dispose();
sha1 = null;
}
public RealFirmwareFile Read(FileInfo fi)
{
var rff = new RealFirmwareFile { FileInfo = fi };
@ -82,7 +91,11 @@ namespace BizHawk.Client.Common
fs.Read(buffer, 0, (int)len);
}
rff.Hash = buffer.HashSHA1(0, (int)len);
//without this, the file reading will make bad GC behaviour
GC.Collect();
sha1.ComputeHash(buffer, 0, (int)len);
rff.Hash = sha1.Hash.BytesToHexString();
dict[rff.Hash] = rff;
_files.Add(rff);
return rff;
@ -94,8 +107,8 @@ namespace BizHawk.Client.Common
public void DoScanAndResolve()
{
var reader = new RealFirmwareReader();
using(var reader = new RealFirmwareReader())
{
// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
var todo = new Queue<DirectoryInfo>();
todo.Enqueue(new DirectoryInfo(PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null)));
@ -190,7 +203,7 @@ namespace BizHawk.Client.Common
// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesnt really use this information right now)
FirmwareDatabase.FirmwareFile ff;
if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash,out ff))
if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out ff))
{
ri.KnownFirmwareFile = ff;
@ -206,7 +219,11 @@ namespace BizHawk.Client.Common
}
}
}
}
}
}
}
} //foreach(firmware record)
} //using(new RealFirmwareReader())
} //DoScanAndResolve()
} //class FirmwareManager
} //namespace

View File

@ -197,7 +197,7 @@ namespace BizHawk.Client.EmuHawk
foreach (ListViewItem lvi in lvFirmwares.Items)
{
var fr = lvi.Tag as FirmwareDatabase.FirmwareRecord;
var ri = Manager.Resolve(fr);
var ri = Manager.Resolve(fr, true);
for(int i=4;i<=6;i++)
lvi.SubItems[i].Text = "";