Browse Source

Fixed thread safety. Handling of null version.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4722 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
18e073d771
  1. 25
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs
  2. 6
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs
  3. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs

25
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

@ -50,8 +50,8 @@ namespace ICSharpCode.XamlBinding @@ -50,8 +50,8 @@ namespace ICSharpCode.XamlBinding
return false;
}
AXmlParser axmlParser;
ICSharpCode.SharpDevelop.ITextBuffer lastParsedContent;
AXmlParser axmlParser = new AXmlParser();
volatile ICSharpCode.SharpDevelop.ITextBufferVersion lastParsedVersion;
/// <summary>
/// Parse the given text and enter read lock.
@ -59,21 +59,24 @@ namespace ICSharpCode.XamlBinding @@ -59,21 +59,24 @@ namespace ICSharpCode.XamlBinding
/// </summary>
public IDisposable ParseAndLock(ICSharpCode.SharpDevelop.ITextBuffer fileContent)
{
// Is fileContent newer?
if (lastParsedContent == null || fileContent.Version.CompareAge(lastParsedContent.Version) > 0) {
// Copy to ensure thread-safety
var lastVer = lastParsedVersion;
if (lastVer == null || // First parse
fileContent.Version == null || // Versioning not supported
fileContent.Version.CompareAge(lastVer) > 0) // Is fileContent newer?
{
axmlParser.Lock.EnterWriteLock();
// Dobuble check, now that we are thread-safe
if (lastParsedContent == null) {
// First parse
axmlParser = new AXmlParser();
if (lastParsedVersion == null || fileContent.Version == null) {
// First parse or verisoning not supported
axmlParser.Parse(fileContent.Text, null);
lastParsedContent = fileContent;
} else if (fileContent.Version.CompareAge(lastParsedContent.Version) > 0) {
lastParsedVersion = fileContent.Version;
} else if (fileContent.Version.CompareAge(lastParsedVersion) > 0) {
// Incremental parse
var changes = lastParsedContent.Version.GetChangesTo(fileContent.Version).
var changes = lastParsedVersion.GetChangesTo(fileContent.Version).
Select(c => new DocumentChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText));
axmlParser.Parse(fileContent.Text, changes);
lastParsedContent = fileContent;
lastParsedVersion = fileContent.Version;
} else {
// fileContent is older - no need to parse
}

6
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/AXmlParser.cs

@ -136,8 +136,10 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -136,8 +136,10 @@ namespace ICSharpCode.AvalonEdit.Xml
/// <summary>
/// Incrementaly parse the given text.
/// You have to hold the write lock.
/// 'changesSinceLastParse' can be null on the first call.
/// </summary>
/// <param name="changesSinceLastParse">
/// Changes since last parse. Null will cause full reparse.
/// </param>
public AXmlDocument Parse(string input, IEnumerable<DocumentChangeEventArgs> changesSinceLastParse)
{
if (!Lock.IsWriteLockHeld)
@ -146,6 +148,8 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -146,6 +148,8 @@ namespace ICSharpCode.AvalonEdit.Xml
// Use changes to invalidate cache
if (changesSinceLastParse != null) {
this.TrackedSegments.UpdateOffsetsAndInvalidate(changesSinceLastParse);
} else {
this.TrackedSegments.InvalidateAll();
}
TagReader tagReader = new TagReader(this, input);

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Xml/TrackedSegmentCollection.cs

@ -54,6 +54,18 @@ namespace ICSharpCode.AvalonEdit.Xml @@ -54,6 +54,18 @@ namespace ICSharpCode.AvalonEdit.Xml
}
}
/// <summary>
/// Invlidates all objects. That is, the whole document has changed.
/// </summary>
/// <remarks> We still have to keep the items becuase they might be in the document </remarks>
public void InvalidateAll()
{
AXmlParser.Log("Invalidating all objects");
foreach(AXmlObject obj in segments.OfType<AXmlObject>()) {
obj.IsCached = false;
}
}
/// <summary> Add object to cache, optionally adding extra memory tracking </summary>
public void AddParsedObject(AXmlObject obj, int? maxTouchedLocation)
{

Loading…
Cancel
Save