Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: pkg/analysis_server/lib/src/analysis_server.dart

Issue 678413003: Avoid analysis server crash when reanalyze invoked during analysis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix unit test Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analysis_server/test/analysis_server_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analysis.server; 5 library analysis.server;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 */ 172 */
173 final DartSdk defaultSdk; 173 final DartSdk defaultSdk;
174 174
175 /** 175 /**
176 * A table mapping [Folder]s to the [AnalysisContext]s associated with them. 176 * A table mapping [Folder]s to the [AnalysisContext]s associated with them.
177 */ 177 */
178 final Map<Folder, AnalysisContext> folderMap = 178 final Map<Folder, AnalysisContext> folderMap =
179 new HashMap<Folder, AnalysisContext>(); 179 new HashMap<Folder, AnalysisContext>();
180 180
181 /** 181 /**
182 * True if a call to [performOperation] is currently executing, or there is a
183 * pending future which will execute [performOperation].
184 */
185 bool operationLoopRunning = false;
186
187 /**
182 * A queue of the operations to perform in this server. 188 * A queue of the operations to perform in this server.
183 *
184 * Invariant: when this queue is non-empty, there is exactly one pending call
185 * to [performOperation] on the event queue. When this list is empty, there a re
186 * no calls to [performOperation] on the event queue.
187 */ 189 */
188 ServerOperationQueue operationQueue; 190 ServerOperationQueue operationQueue;
189 191
190 /** 192 /**
191 * A set of the [ServerService]s to send notifications for. 193 * A set of the [ServerService]s to send notifications for.
192 */ 194 */
193 Set<ServerService> serverServices = new HashSet<ServerService>(); 195 Set<ServerService> serverServices = new HashSet<ServerService>();
194 196
195 /** 197 /**
196 * A table mapping [AnalysisService]s to the file paths for which these 198 * A table mapping [AnalysisService]s to the file paths for which these
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 void fileAnalyzed(ChangeNotice notice) { 263 void fileAnalyzed(ChangeNotice notice) {
262 if (contextDirectoryManager.isInAnalysisRoot(notice.source.fullName)) { 264 if (contextDirectoryManager.isInAnalysisRoot(notice.source.fullName)) {
263 _onFileAnalyzedController.add(notice); 265 _onFileAnalyzedController.add(notice);
264 } 266 }
265 } 267 }
266 268
267 /** 269 /**
268 * Schedules execution of the given [ServerOperation]. 270 * Schedules execution of the given [ServerOperation].
269 */ 271 */
270 void scheduleOperation(ServerOperation operation) { 272 void scheduleOperation(ServerOperation operation) {
271 bool wasEmpty = operationQueue.isEmpty;
272 addOperation(operation); 273 addOperation(operation);
273 if (wasEmpty) { 274 if (!operationLoopRunning) {
274 _schedulePerformOperation(); 275 _schedulePerformOperation();
276 operationLoopRunning = true;
275 } 277 }
276 } 278 }
277 279
278 /** 280 /**
279 * Schedules analysis of the given context. 281 * Schedules analysis of the given context.
280 */ 282 */
281 void schedulePerformAnalysisOperation(AnalysisContext context) { 283 void schedulePerformAnalysisOperation(AnalysisContext context) {
282 _onAnalysisStartedController.add(context); 284 _onAnalysisStartedController.add(context);
283 scheduleOperation(new PerformAnalysisOperation(context, false)); 285 scheduleOperation(new PerformAnalysisOperation(context, false));
284 } 286 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 */ 480 */
479 bool isPriorityContext(AnalysisContext context) { 481 bool isPriorityContext(AnalysisContext context) {
480 // TODO(scheglov) implement support for priority sources/contexts 482 // TODO(scheglov) implement support for priority sources/contexts
481 return false; 483 return false;
482 } 484 }
483 485
484 /** 486 /**
485 * Perform the next available [ServerOperation]. 487 * Perform the next available [ServerOperation].
486 */ 488 */
487 void performOperation() { 489 void performOperation() {
490 assert(operationLoopRunning);
488 if (!running) { 491 if (!running) {
489 // An error has occurred, or the connection to the client has been 492 // An error has occurred, or the connection to the client has been
490 // closed, since this method was scheduled on the event queue. So 493 // closed, since this method was scheduled on the event queue. So
491 // don't do anything. Instead clear the operation queue. 494 // don't do anything. Instead clear the operation queue.
492 operationQueue.clear(); 495 operationQueue.clear();
496 operationLoopRunning = false;
493 return; 497 return;
494 } 498 }
495 // prepare next operation 499 // prepare next operation
496 ServerOperation operation = operationQueue.take(); 500 ServerOperation operation = operationQueue.take();
501 if (operation == null) {
502 // This can happen if the operation queue is cleared while the operation
503 // loop is in progress. No problem; we just need to exit the operation
504 // loop and wait for the next operation to be added.
505 operationLoopRunning = false;
506 return;
507 }
497 sendStatusNotification(operation); 508 sendStatusNotification(operation);
498 // perform the operation 509 // perform the operation
499 try { 510 try {
500 operation.perform(this); 511 operation.perform(this);
501 } catch (exception, stackTrace) { 512 } catch (exception, stackTrace) {
502 AnalysisEngine.instance.logger.logError("${exception}\n${stackTrace}"); 513 AnalysisEngine.instance.logger.logError("${exception}\n${stackTrace}");
503 if (rethrowExceptions) { 514 if (rethrowExceptions) {
504 throw new AnalysisException( 515 throw new AnalysisException(
505 'Unexpected exception during analysis', 516 'Unexpected exception during analysis',
506 new CaughtException(exception, stackTrace)); 517 new CaughtException(exception, stackTrace));
507 } 518 }
508 _sendServerErrorNotification(exception, stackTrace); 519 _sendServerErrorNotification(exception, stackTrace);
509 shutdown(); 520 shutdown();
510 } finally { 521 } finally {
511 if (!operationQueue.isEmpty) { 522 if (!operationQueue.isEmpty) {
512 _schedulePerformOperation(); 523 _schedulePerformOperation();
513 } else { 524 } else {
514 sendStatusNotification(null); 525 sendStatusNotification(null);
515 _onAnalysisCompleteController.add(null); 526 _onAnalysisCompleteController.add(null);
527 operationLoopRunning = false;
Brian Wilkerson 2014/10/28 20:37:14 If an exception occurs in sendStatusNotification,
516 } 528 }
517 } 529 }
518 } 530 }
519 531
520 /** 532 /**
521 * Trigger reanalysis of all files from disk. 533 * Trigger reanalysis of all files from disk.
522 */ 534 */
523 void reanalyze() { 535 void reanalyze() {
524 // Clear any operations that are pending. 536 // Clear any operations that are pending.
525 operationQueue.clear(); 537 operationQueue.clear();
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 // send the notification 947 // send the notification
936 channel.sendNotification( 948 channel.sendNotification(
937 new ServerErrorParams( 949 new ServerErrorParams(
938 true, 950 true,
939 exceptionString, 951 exceptionString,
940 stackTraceString).toNotification()); 952 stackTraceString).toNotification());
941 } 953 }
942 } 954 }
943 955
944 typedef void OptionUpdater(AnalysisOptionsImpl options); 956 typedef void OptionUpdater(AnalysisOptionsImpl options);
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/analysis_server_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698