diff --git a/ide_plugins/vs/coati_plugin_vs.vsix b/ide_plugins/vs/coati_plugin_vs.vsix
index c65a1c3a..71ef196a 100644
Binary files a/ide_plugins/vs/coati_plugin_vs.vsix and b/ide_plugins/vs/coati_plugin_vs.vsix differ
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPlugin.csproj b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPlugin.csproj
index cc996f65..f7dd7241 100644
--- a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPlugin.csproj
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPlugin.csproj
@@ -162,6 +162,7 @@
+
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPluginPackage.cs b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPluginPackage.cs
index 10d786d5..384507e1 100644
--- a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPluginPackage.cs
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/CoatiPluginPackage.cs
@@ -366,35 +366,11 @@ namespace CoatiSoftware.CoatiPlugin
_cdbList.AppendOrUpdate(creationResult._cdb);
_cdbList.SaveMetaData();
- // string metaData = creationResult._cdb.SerializeMetaDataXML();
+ Wizard.WindowCDBReady dialog = new Wizard.WindowCDBReady();
+ dialog.setData(creationResult);
+ dialog.ShowDialog();
-
- // Utility.DataUtility.GetInstance().AppendData(metaData);
-
- if (WriteCDBToFile(creationResult._cdb, creationResult._cdbDirectory, creationResult._cdbName))
- {
- Wizard.WindowCDBReady dialog = new Wizard.WindowCDBReady();
- dialog.setData(creationResult);
- dialog.ShowDialog();
-
- _cdbList.Refresh();
- }
- else
- {
- string title = "Error";
- string text = "Failed to write CDB '" + creationResult._cdbName + "' to directory \"" + creationResult._cdbDirectory + "\"\n";
-
- if (LoggingEnabled)
- {
- text += "See log for details.";
- }
- else
- {
- text += "Consider enabling logging to provide additional information (Tools->Options->Coati).";
- }
-
- DialogResult result = MessageBox.Show(text, title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
- }
+ _cdbList.Refresh();
}
else
{
@@ -402,39 +378,6 @@ namespace CoatiSoftware.CoatiPlugin
}
}
- private bool WriteCDBToFile(SolutionParser.CompilationDatabase cdb, string directory, string fileName)
- {
- try
- {
- Logging.Logging.LogInfo("Serializing " + cdb.CommandObjectCount + " command objects.");
-
- System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
- watch.Start();
- string content = cdb.SerializeJSON();
- watch.Stop();
- Logging.Logging.LogInfo("Done serializing: " + watch.ElapsedMilliseconds + " ms");
-
- File.WriteAllText(directory + "\\" + fileName + ".json", content);
- }
- catch(Exception e)
- {
- string text = "Failed to write CDB '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(fileName) + "' to directory \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(directory) + "\"\n";
- Logging.Logging.LogError(text);
- Logging.Logging.LogError("Exception: " + e.Message);
-
- _cdbList.UnloadCDBs();
-
- return false;
- }
-
- string message = "The CDB '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(fileName) + "' was created at directory \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(directory) + "\"\n";
- Logging.Logging.LogInfo(message);
-
- _cdbList.UnloadCDBs();
-
- return true;
- }
-
private void MenuItemCallback(object sender, EventArgs e)
{
MenuCommand menuCommand = sender as MenuCommand;
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/SolutionParser/CompilationDatabase.cs b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/SolutionParser/CompilationDatabase.cs
index c247e70f..af73e9a6 100644
--- a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/SolutionParser/CompilationDatabase.cs
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/SolutionParser/CompilationDatabase.cs
@@ -2,6 +2,9 @@
using System.Xml.Serialization;
using System.Xml;
using Newtonsoft.Json.Linq;
+using System.IO;
+using System.Threading;
+using System;
namespace CoatiSoftware.CoatiPlugin.SolutionParser
{
@@ -67,14 +70,9 @@ namespace CoatiSoftware.CoatiPlugin.SolutionParser
get { return _commandObjects.Count; }
}
- public void AddOrUpdateCommandObject(CommandObject commandObject)
+ public void AddOrUpdateCommandObject(CommandObject commandObject, bool saveImmediatly = false)
{
_commandObjects.Add(commandObject); // updating is not efficient as it is
-
- //if (TryUpdateCommandObject(commandObject) == false)
- //{
- // _commandObjects.Add(commandObject);
- //}
}
// remove commandObjects for removed files
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Utility/QueuedFileWriter.cs b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Utility/QueuedFileWriter.cs
new file mode 100644
index 00000000..7d989968
--- /dev/null
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Utility/QueuedFileWriter.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+
+namespace CoatiSoftware.CoatiPlugin.Utility
+{
+ class QueuedFileWriter
+ {
+ private bool _working = false;
+ Thread _workerThread = null;
+
+ private static ReaderWriterLockSlim _statusLock = new ReaderWriterLockSlim();
+ private static ReaderWriterLockSlim _queueLock = new ReaderWriterLockSlim();
+ private static ReaderWriterLockSlim _fileLock = new ReaderWriterLockSlim();
+
+ private Queue _inputQueue = new Queue();
+ private Queue _outputQueue = new Queue();
+
+ private string _targetDirectory = "";
+ private string _fileName = "";
+
+ private int _messagesReceived = 0;
+ private int _messageWrittenCount = 0;
+
+ public string TargetDirectory
+ {
+ get { return _targetDirectory; }
+ set { _targetDirectory = value; }
+ }
+
+ public string FileName
+ {
+ get { return _fileName; }
+ set { _fileName = value; }
+ }
+
+ public void pushMessage(string message)
+ {
+ _queueLock.EnterWriteLock();
+ _messagesReceived++;
+ try
+ {
+ _inputQueue.Enqueue(message);
+ }
+ catch(Exception e)
+ {
+ Logging.Logging.LogError(e.Message);
+ }
+ finally
+ {
+ _queueLock.ExitWriteLock();
+ }
+ }
+
+ public void startWorking()
+ {
+ _statusLock.EnterReadLock();
+ if (_working == true)
+ {
+ return;
+ }
+ _statusLock.ExitReadLock();
+
+
+ _statusLock.EnterWriteLock();
+ _working = true;
+ _workerThread = new Thread(new ThreadStart(work));
+ _workerThread.Start();
+ _statusLock.ExitWriteLock();
+ }
+
+ public void stopWorking()
+ {
+ _statusLock.EnterWriteLock();
+ _working = false;
+ _statusLock.ExitWriteLock();
+
+ if(_workerThread != null)
+ {
+ _workerThread.Join();
+ }
+
+ // write remaining messages if stop was called
+ _queueLock.EnterWriteLock();
+ try
+ {
+ writeQueueToFile(ref _inputQueue);
+ writeQueueToFile(ref _outputQueue);
+
+ Logging.Logging.LogInfo("final commit done");
+ }
+ catch(Exception e)
+ {
+ Logging.Logging.LogError(e.Message);
+ }
+ finally
+ {
+ _queueLock.ExitWriteLock();
+ }
+
+ Logging.Logging.LogInfo("Messages received: " + _messagesReceived);
+ Logging.Logging.LogInfo("Messages written: " + _messageWrittenCount);
+ }
+
+ private void work()
+ {
+ bool working = true;
+
+ while(working)
+ {
+ commit();
+
+ _statusLock.EnterReadLock();
+ working = _working;
+ _statusLock.ExitReadLock();
+ }
+ }
+
+ private void commit()
+ {
+ _queueLock.EnterWriteLock();
+
+ Queue tmpQueue = _inputQueue;
+ _inputQueue = _outputQueue;
+ _outputQueue = tmpQueue;
+
+ _queueLock.ExitWriteLock();
+
+
+ writeQueueToFile(ref _outputQueue);
+ }
+
+ private void writeQueueToFile(ref Queue messageQueue)
+ {
+ _fileLock.EnterWriteLock();
+ try
+ {
+ while(messageQueue.Count > 0)
+ {
+ _messageWrittenCount++;
+
+ string message = messageQueue.Dequeue();
+
+ File.AppendAllText(_targetDirectory + "\\" + _fileName, message);
+ }
+ }
+ catch (Exception e)
+ {
+ Logging.Logging.LogError(e.Message);
+ }
+ finally
+ {
+ _fileLock.ExitWriteLock();
+ }
+ }
+ }
+}
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Wizard/WindowCreateCDB.cs b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Wizard/WindowCreateCDB.cs
index 26477174..19e6fde5 100644
--- a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Wizard/WindowCreateCDB.cs
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/Wizard/WindowCreateCDB.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.IO;
using System.Threading.Tasks;
+using System.Threading;
using System.Windows.Forms;
namespace CoatiSoftware.CoatiPlugin.Wizard
@@ -35,6 +37,9 @@ namespace CoatiSoftware.CoatiPlugin.Wizard
private int _threadCount = 1;
+ private static object _lockObject = new object();
+ private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
+
public OnFinishedCreatingCDB CallbackOnFinishedCreatingCDB
{
get { return _onFinishedCreateCDB; }
@@ -176,6 +181,21 @@ namespace CoatiSoftware.CoatiPlugin.Wizard
private SolutionParser.CompilationDatabase CreateCommandObjects()
{
SolutionParser.CompilationDatabase cdb = new SolutionParser.CompilationDatabase();
+ cdb.Directory = _targetDir;
+ cdb.Name = _fileName;
+
+ File.WriteAllText(_targetDir + "\\" + _fileName + ".json", "");
+ File.AppendAllText(_targetDir + "\\" + _fileName + ".json", "[\n");
+
+ // Mutex commandObjectMutex = new Mutex();
+
+ object lockObject = new object();
+ object lockObject2 = new object();
+
+ Utility.QueuedFileWriter fileWriter = new Utility.QueuedFileWriter();
+ fileWriter.FileName = _fileName + ".json";
+ fileWriter.TargetDirectory = _targetDir;
+ fileWriter.startWorking();
try
{
@@ -185,8 +205,6 @@ namespace CoatiSoftware.CoatiPlugin.Wizard
List tasks = new List();
- Object lockObject = new Object();
-
int projectsProcessed = 0;
foreach (EnvDTE.Project project in _projects)
{
@@ -198,34 +216,45 @@ namespace CoatiSoftware.CoatiPlugin.Wizard
{
List commandObjects = SolutionParser.SolutionParser.CreateCommandObjects(project, _configurationName, _platformName, _cStandard);
- lock(lockObject)
+ lock (_lockObject)
{
projectsProcessed++;
}
-
+
float relativProgress = (float)projectsProcessed / (float)_projects.Count;
Logging.Logging.LogInfo("Processing project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\"");
backgroundWorker1.ReportProgress((int)(relativProgress * 100), "Processing project \"" + project.Name + "\"");
foreach (SolutionParser.CommandObject obj in commandObjects)
{
- cdb.AddOrUpdateCommandObject(obj);
+ // cdb.AddOrUpdateCommandObject(obj, false); // since the data is written to file right away now, no need to store it
+ // the cdb is however still needed to store some meta data later
+
+ fileWriter.pushMessage(obj.SerializeJSON() + ",");
}
});
tasks.Add(t);
}
+
+
int threadCount = System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
Task.WaitAll(tasks.ToArray());
+ fileWriter.stopWorking();
+
backgroundWorker1.ReportProgress(100, "Writing data to file. This might take several minutes...");
}
catch(Exception e)
{
Logging.Logging.LogError("Failed to create CDB: " + e.Message);
}
+ finally
+ {
+ File.AppendAllText(_targetDir + "\\" + _fileName + ".json", "\n]");
+ }
return cdb;
}
diff --git a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/source.extension.vsixmanifest b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/source.extension.vsixmanifest
index c55f153d..52f86ee0 100644
--- a/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/source.extension.vsixmanifest
+++ b/ide_plugins/vs/vs2015/CoatiPlugin/CoatiPlugin/source.extension.vsixmanifest
@@ -1,7 +1,7 @@
-
+
CoatiPlugin
This package allows Coati to communicate with Visual Studio and vice versa.
http://www.coati.io/