Chromium Code Reviews| Index: pkg/analysis_server/lib/src/analysis_server.dart |
| diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart |
| index c343d22dae5efd29914ec674b0d9c9bf6e01a76b..d9eea8989ba6e6353864809bc71cbfb639541ad2 100644 |
| --- a/pkg/analysis_server/lib/src/analysis_server.dart |
| +++ b/pkg/analysis_server/lib/src/analysis_server.dart |
| @@ -179,11 +179,13 @@ class AnalysisServer { |
| new HashMap<Folder, AnalysisContext>(); |
| /** |
| + * True if a call to [performOperation] is currently executing, or there is a |
| + * pending future which will execute [performOperation]. |
| + */ |
| + bool operationLoopRunning = false; |
| + |
| + /** |
| * A queue of the operations to perform in this server. |
| - * |
| - * Invariant: when this queue is non-empty, there is exactly one pending call |
| - * to [performOperation] on the event queue. When this list is empty, there are |
| - * no calls to [performOperation] on the event queue. |
| */ |
| ServerOperationQueue operationQueue; |
| @@ -268,10 +270,10 @@ class AnalysisServer { |
| * Schedules execution of the given [ServerOperation]. |
| */ |
| void scheduleOperation(ServerOperation operation) { |
| - bool wasEmpty = operationQueue.isEmpty; |
| addOperation(operation); |
| - if (wasEmpty) { |
| + if (!operationLoopRunning) { |
| _schedulePerformOperation(); |
| + operationLoopRunning = true; |
| } |
| } |
| @@ -485,15 +487,24 @@ class AnalysisServer { |
| * Perform the next available [ServerOperation]. |
| */ |
| void performOperation() { |
| + assert(operationLoopRunning); |
| if (!running) { |
| // An error has occurred, or the connection to the client has been |
| // closed, since this method was scheduled on the event queue. So |
| // don't do anything. Instead clear the operation queue. |
| operationQueue.clear(); |
| + operationLoopRunning = false; |
| return; |
| } |
| // prepare next operation |
| ServerOperation operation = operationQueue.take(); |
| + if (operation == null) { |
| + // This can happen if the operation queue is cleared while the operation |
| + // loop is in progress. No problem; we just need to exit the operation |
| + // loop and wait for the next operation to be added. |
| + operationLoopRunning = false; |
| + return; |
| + } |
| sendStatusNotification(operation); |
| // perform the operation |
| try { |
| @@ -513,6 +524,7 @@ class AnalysisServer { |
| } else { |
| sendStatusNotification(null); |
| _onAnalysisCompleteController.add(null); |
| + operationLoopRunning = false; |
|
Brian Wilkerson
2014/10/28 20:37:14
If an exception occurs in sendStatusNotification,
|
| } |
| } |
| } |