Browse Source

BuildWorker: swap communication and build threads.

This is an attempt to fix http://community.sharpdevelop.net/forums/t/15654.aspx - BuildWorker40 hangs on windows 7 x64bit when invoking the markup compiler.
According the the report in the forums, the problem disappears when MSBuild is invoked on the main thread, and communication is suspended while the build is in progress (breaking cancellation).
This patch also moves the communication onto a background thread, fixing build cancellation. This might solve the problem if the hang was somehow related to the thread MSBuild was running on. However, if the AppDomain unload fails due to the thread stuck reading from the named pipe, the build worker might continue hanging with this patch.
4.2
Daniel Grunwald 13 years ago
parent
commit
bbd58339cd
  1. 55
      src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs

55
src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs

@ -18,9 +18,10 @@ namespace ICSharpCode.SharpDevelop.BuildWorker @@ -18,9 +18,10 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
{
sealed class Program
{
static HostProcess host;
HostProcess host;
BuildJob currentJob;
bool requestCancellation;
bool requestProcessShutdown;
[STAThread]
internal static void Main(string[] args)
@ -29,8 +30,12 @@ namespace ICSharpCode.SharpDevelop.BuildWorker @@ -29,8 +30,12 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
if (args.Length == 3 && args[0] == "worker") {
try {
host = new HostProcess(args[1], args[2]);
host.Run(new Program().DataReceived);
Program program = new Program();
program.host = new HostProcess(args[1], args[2]);
Thread communicationThread = new Thread(program.RunCommunicationThread);
communicationThread.Name = "Communication";
communicationThread.Start();
program.RunBuildThread();
} catch (Exception ex) {
ShowMessageBox(ex.ToString());
}
@ -42,10 +47,25 @@ namespace ICSharpCode.SharpDevelop.BuildWorker @@ -42,10 +47,25 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
}
}
void RunCommunicationThread()
{
try {
host.Run(DataReceived);
} catch (Exception ex) {
ShowMessageBox(ex.ToString());
} finally {
lock (this) {
requestProcessShutdown = true;
Monitor.PulseAll(this);
}
}
}
readonly MSBuildWrapper buildWrapper = new MSBuildWrapper();
void DataReceived(string command, BinaryReader reader)
{
// called on communication thread
switch (command) {
case "StartBuild":
StartBuild(BuildJob.ReadFrom(reader));
@ -86,28 +106,26 @@ namespace ICSharpCode.SharpDevelop.BuildWorker @@ -86,28 +106,26 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void StartBuild(BuildJob job)
{
// called on communication thread
if (job == null)
throw new ArgumentNullException("job");
Program.Log("Got job:");
Program.Log(job.ToString());
lock (this) {
if (currentJob != null)
throw new InvalidOperationException("Already running a job");
currentJob = job;
requestCancellation = false;
Monitor.PulseAll(this);
}
#if WORKERDEBUG
Console.Title = "BuildWorker - " + Path.GetFileName(job.ProjectFileName);
#endif
Program.Log("Got job:");
Program.Log(job.ToString());
Program.Log("Start build thread");
Thread thread = new Thread(RunThread);
thread.Name = "Build thread";
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public void CancelBuild()
{
// called on communication thread
Program.Log("CancelBuild()");
lock (this) {
if (!requestCancellation) {
@ -117,8 +135,21 @@ namespace ICSharpCode.SharpDevelop.BuildWorker @@ -117,8 +135,21 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
void RunThread()
void RunBuildThread()
{
while (true) {
// Wait for next job, or for shutdown
lock (this) {
while (currentJob == null && !requestProcessShutdown)
Monitor.Wait(this);
if (requestProcessShutdown)
break;
}
PerformBuild();
}
}
void PerformBuild()
{
Program.Log("In build thread");
bool success = false;

Loading…
Cancel
Save