Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions src/VisualStudio/Debugger.Support/RTLink/RtLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ static RtLink()
{
AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoadEventHandler;
var loadedAssemblies = new HashSet<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
do
lock (LoadedAssemblies)
{
LoadedAssemblies.UnionWith(loadedAssemblies);
loadedAssemblies = new HashSet<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
loadedAssemblies.RemoveWhere(a => a.IsDynamic);
loadedAssemblies.ExceptWith(LoadedAssemblies);
} while (loadedAssemblies.Count > 0);

do
{
LoadedAssemblies.UnionWith(loadedAssemblies);
loadedAssemblies = new HashSet<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
loadedAssemblies.RemoveWhere(a => a.IsDynamic);
loadedAssemblies.ExceptWith(LoadedAssemblies);
} while (loadedAssemblies.Count > 0);
}
}


Expand All @@ -64,7 +66,11 @@ private static void AssemblyLoadEventHandler(object sender, AssemblyLoadEventArg
static Type FindType(string name, string asmName, out string error)
{
error = null;
var asm = LoadedAssemblies.First(a => a.FullName.ToLower().Contains(asmName.ToLower()));
Assembly asm;
lock (LoadedAssemblies)
{
asm = LoadedAssemblies.FirstOrDefault(a => a.FullName.ToLower().Contains(asmName.ToLower()));
}
if (asm == null)
{
error = string.Format(AssemblyNotFound, asmName);
Expand Down Expand Up @@ -100,8 +106,11 @@ static PropertyInfo FindProperty(this Type type, string Name, BindingFlags flags
#endregion
public static bool IsRTLoaded()
{
return LoadedAssemblies.Any(a => a.FullName.ToLower().Contains("xsharp.rt")) &&
LoadedAssemblies.Any(a => a.FullName.ToLower().Contains("xsharp.core"));
lock (LoadedAssemblies)
{
return LoadedAssemblies.Any(a => a.FullName.ToLower().Contains("xsharp.rt")) &&
LoadedAssemblies.Any(a => a.FullName.ToLower().Contains("xsharp.core"));
}
}

public static string GetGlobals()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public class XSharpClassifier : IClassifier
private readonly List<String> _xtraKeywords;
private XSharpLineState _lineState;
private XSharpLineKeywords _lineKeywords;
private bool IsLexing = false;
private bool IsStarted = false;
private volatile bool IsLexing = false;
private volatile bool IsStarted = false;
private bool _needsKeywords = false;
private bool forceRepaint = false;

Expand Down
7 changes: 6 additions & 1 deletion src/VisualStudio/LanguageService/XMLDoc/XSharpXMLDoc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static public class XSharpXMLDocTools
static IVsXMLMemberIndexService _XMLMemberIndexService ;
static string coreLoc ;
static IVsXMLMemberIndex coreIndex ;
static readonly object _initLock = new object();
static XSharpXMLDocTools()
{
_memberIndexes = new Dictionary<string, IVsXMLMemberIndex>();
Expand All @@ -46,8 +47,12 @@ static void init()

static bool GetIndex()
{
if (_XMLMemberIndexService == null)
if (_XMLMemberIndexService != null)
return true;
lock (_initLock)
{
if (_XMLMemberIndexService != null)
return true;
ThreadHelper.JoinableTaskFactory.Run(async ( )=>
{
_XMLMemberIndexService = await VS.GetServiceAsync<SVsXMLMemberIndexService, IVsXMLMemberIndexService>();
Expand Down
37 changes: 27 additions & 10 deletions src/VisualStudio/ProjectPackage/Commands/CommandEditProjectFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.VisualStudio.Threading;

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand All @@ -18,13 +19,14 @@ namespace XSharp.Project
[Command(PackageIds.idEditProjectFile)]
internal sealed class CommandEditProjectFile : BaseCommand<CommandEditProjectFile>
{
static Dictionary<string, string> tempProjectFiles; // key is the project file, value is the temp file
static ConcurrentDictionary<string, string> tempProjectFiles; // key is the project file, value is the temp file
static string tempProjectDir;
static volatile bool _eventsSubscribed = false;
static CommandEditProjectFile()
{
tempProjectDir = Path.Combine(Path.GetTempPath(), "XSharp.Intellisense");
Directory.CreateDirectory(tempProjectDir);
tempProjectFiles = new Dictionary<string, string>();
tempProjectFiles = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
protected override void BeforeQueryStatus(EventArgs e)
{
Expand All @@ -38,8 +40,14 @@ private async Task CheckAvailabilityAsync()
protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
{
var project = await VS.Solutions.GetActiveProjectAsync();
VS.Events.DocumentEvents.Saved += DocumentEvents_Saved;
VS.Events.DocumentEvents.Closed += DocumentEvents_Closed;
// Unsubscribe before subscribing to prevent duplicate registrations
// if ExecuteAsync is called multiple times.
if (!_eventsSubscribed)
{
VS.Events.DocumentEvents.Saved += DocumentEvents_Saved;
VS.Events.DocumentEvents.Closed += DocumentEvents_Closed;
_eventsSubscribed = true;
}


var projectNode = XSharpProjectNode.FindProject(project.FullPath);
Expand Down Expand Up @@ -82,17 +90,26 @@ private void DocumentEvents_Saved(string obj)

private void DocumentEvents_Closed(string obj)
{
// Find the matching key without modifying the collection during iteration.
string keyToRemove = null;
foreach (var item in tempProjectFiles)
{
if ( item.Value == obj)
if (item.Value == obj)
{
keyToRemove = item.Key;
break;
}
}
if (keyToRemove != null && tempProjectFiles.TryRemove(keyToRemove, out _))
{
File.Delete(obj);
// VS document events and commands all execute on the UI thread, so no other
// thread can insert a new entry between TryRemove and IsEmpty.
if (tempProjectFiles.IsEmpty)
{

tempProjectFiles.Remove(item.Key);
VS.Events.DocumentEvents.Closed -= DocumentEvents_Closed;
VS.Events.DocumentEvents.Saved -= DocumentEvents_Saved;
File.Delete(item.Value);
break;

_eventsSubscribed = false;
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions src/VisualStudio/ProjectPackage/List/ErrorList/ErrorListManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal class ErrorListManager : ListManager<IErrorListItem>
static ErrorListProvider _listprovider = null;
static IErrorList _errorList = null;
static ITableManager _manager = null;
static readonly object _initLock = new object();


static ErrorListManager()
Expand All @@ -39,11 +40,16 @@ static void GetErrorList()
{
if (_errorList != null)
return;
_errorList = XSharpProjectPackage.XInstance.ErrorList;
if (_errorList != null)
lock (_initLock)
{
_manager = _errorList.TableControl.Manager;
_listprovider = new ErrorListProvider(_manager);
if (_errorList != null)
return;
_errorList = XSharpProjectPackage.XInstance.ErrorList;
if (_errorList != null)
{
_manager = _errorList.TableControl.Manager;
_listprovider = new ErrorListProvider(_manager);
}
}
}
internal ErrorListManager(XSharpProjectNode node) : base(node)
Expand Down
14 changes: 10 additions & 4 deletions src/VisualStudio/ProjectPackage/List/TaskList/TaskListManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,23 @@ internal class TaskListManager : ListManager<ITaskListItem>
static ListProvider _listprovider = null;
static ITaskList _taskList;
static ITableManager _manager;
static readonly object _initLock = new object();


static void GetTaskList()
{
if (_taskList != null)
return;
_taskList = XSharpProjectPackage.XInstance.TaskList;
if (_taskList != null)
lock (_initLock)
{
_manager = _taskList.TableControl.Manager;
_listprovider = new TaskListProvider(_manager);
if (_taskList != null)
return;
_taskList = XSharpProjectPackage.XInstance.TaskList;
if (_taskList != null)
{
_manager = _taskList.TableControl.Manager;
_listprovider = new TaskListProvider(_manager);
}
}
}

Expand Down
20 changes: 11 additions & 9 deletions src/VisualStudio/ProjectPackage/Nodes/XSharpProjectNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ public partial class XSharpProjectNode : XProjectNode, IVsSingleFileGeneratorFac
static List<XSharpProjectNode> nodes = new List<XSharpProjectNode>();
internal static XSharpProjectNode FindProject(string url)
{
var file = System.IO.Path.GetFileName(url);
foreach (var proj in nodes)
lock (nodes)
{
if (string.Compare(proj.FileName, url, true) == 0)
return proj;
var pFile = System.IO.Path.GetFileName(proj.FileName);
if (string.Compare(pFile, url, true) == 0)
return proj;
var file = System.IO.Path.GetFileName(url);
foreach (var proj in nodes)
{
if (string.Compare(proj.FileName, url, true) == 0)
return proj;
var pFile = System.IO.Path.GetFileName(proj.FileName);
if (string.Compare(pFile, url, true) == 0)
return proj;
}
}

return null;
}

Expand All @@ -86,7 +88,7 @@ static XSharpProjectNode()
_changedProjectFiles = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
internal static IDictionary<string, string> ChangedProjectFiles => _changedProjectFiles;
internal static XSharpProjectNode[] AllProjects => nodes.ToArray();
internal static XSharpProjectNode[] AllProjects { get { lock (nodes) { return nodes.ToArray(); } } }

#region Constants
internal const string ProjectTypeName = XSharpConstants.LanguageName;
Expand Down