Increase parsing thread stack size to avoid stack overflow (#486)

* Increase parsing thread stack size to avoid stack overflow

* Fix extra space

* Remove extra spaces
This commit is contained in:
Karl Burtram
2017-10-10 16:33:04 -07:00
committed by GitHub
parent 11cb154d6d
commit 4945aead96
2 changed files with 31 additions and 15 deletions

View File

@@ -17,6 +17,8 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// </summary> /// </summary>
public class BindingQueue<T> : IDisposable where T : IBindingContext, new() public class BindingQueue<T> : IDisposable where T : IBindingContext, new()
{ {
internal const int QueueThreadStackSize = 5 * 1024 * 1024;
private CancellationTokenSource processQueueCancelToken = new CancellationTokenSource(); private CancellationTokenSource processQueueCancelToken = new CancellationTokenSource();
private ManualResetEvent itemQueuedEvent = new ManualResetEvent(initialState: false); private ManualResetEvent itemQueuedEvent = new ManualResetEvent(initialState: false);
@@ -264,15 +266,18 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
// execute the binding operation // execute the binding operation
object result = null; object result = null;
CancellationTokenSource cancelToken = new CancellationTokenSource(); CancellationTokenSource cancelToken = new CancellationTokenSource();
var bindTask = Task.Run(() =>
// run the operation in a separate thread
var bindThread = new Thread(() =>
{ {
result = queueItem.BindOperation( result = queueItem.BindOperation(
bindingContext, bindingContext,
cancelToken.Token); cancelToken.Token);
}); }, BindingQueue<T>.QueueThreadStackSize);
bindThread.Start();
// check if the binding tasks completed within the binding timeout // check if the binding tasks completed within the binding timeout
if (bindTask.Wait(bindTimeout)) if (bindThread.Join(bindTimeout))
{ {
queueItem.Result = result; queueItem.Result = result;
} }
@@ -285,12 +290,17 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
queueItem.Result = queueItem.TimeoutOperation(bindingContext); queueItem.Result = queueItem.TimeoutOperation(bindingContext);
} }
lockTaken = false; lockTaken = false;
bindTask.ContinueWith((a) => bindingContext.BindingLock.Set()); Task.Run(() =>
} {
} // wait for the operation to complete before releasing the lock
bindThread.Join();
bindingContext.BindingLock.Set();
});
}
}
catch (Exception ex) catch (Exception ex)
{ {
// catch and log any exceptions raised in the binding calls // catch and log any exceptions raised in the binding calls

View File

@@ -762,13 +762,19 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
if (connInfo == null || !parseInfo.IsConnected) if (connInfo == null || !parseInfo.IsConnected)
{ {
// parse current SQL file contents to retrieve a list of errors // parse on separate thread so stack size can be increased
ParseResult parseResult = Parser.IncrementalParse( var parseThread = new Thread(() =>
scriptFile.Contents, {
parseInfo.ParseResult, // parse current SQL file contents to retrieve a list of errors
this.DefaultParseOptions); ParseResult parseResult = Parser.IncrementalParse(
scriptFile.Contents,
parseInfo.ParseResult,
this.DefaultParseOptions);
parseInfo.ParseResult = parseResult; parseInfo.ParseResult = parseResult;
}, ConnectedBindingQueue.QueueThreadStackSize);
parseThread.Start();
parseThread.Join();
} }
else else
{ {