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

Unified Diff: pkg/analyzer/lib/src/context/cache.dart

Issue 1426843002: Fix for leaking AnalysisCache and AnalysisContext instances. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/context/context.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/context/cache.dart
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 4443dfaad38d423c09730c98fc92551fe97e4f19..a6094216f7205e4d34128077c4502b53c45a28c6 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -41,20 +41,35 @@ class AnalysisCache {
final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
new ReentrantSynchronousStream<InvalidatedResult>();
+ final List<
+ ReentrantSynchronousStreamSubscription> onResultInvalidatedPartitionSubscriptions = <
+ ReentrantSynchronousStreamSubscription>[];
+
/**
- * Initialize a newly created cache to have the given [partitions]. The
+ * Initialize a newly created cache to have the given [_partitions]. The
* partitions will be searched in the order in which they appear in the array,
* so the most specific partition (usually an [SdkCachePartition]) should be
* first and the most general (usually a [UniversalCachePartition]) last.
*/
AnalysisCache(this._partitions) {
for (CachePartition partition in _partitions) {
- partition.onResultInvalidated.listen((InvalidatedResult event) {
+ ReentrantSynchronousStreamSubscription<InvalidatedResult> subscription =
+ partition.onResultInvalidated.listen((InvalidatedResult event) {
onResultInvalidated.add(event);
});
+ onResultInvalidatedPartitionSubscriptions.add(subscription);
}
}
+ /**
+ * Return an iterator returning all of the [Source] targets.
+ */
+ Iterable<Source> get sources {
+ return _partitions
+ .map((CachePartition partition) => partition._sources)
+ .expand((Iterable<Source> sources) => sources);
+ }
+
// TODO(brianwilkerson) Implement or delete this.
// /**
// * Return information about each of the partitions in this cache.
@@ -73,12 +88,13 @@ class AnalysisCache {
// }
/**
- * Return an iterator returning all of the [Source] targets.
+ * Free any allocated resources and references.
*/
- Iterable<Source> get sources {
- return _partitions
- .map((CachePartition partition) => partition._sources)
- .expand((Iterable<Source> sources) => sources);
+ void dispose() {
+ for (ReentrantSynchronousStreamSubscription subscription
+ in onResultInvalidatedPartitionSubscriptions) {
+ subscription.cancel();
+ }
}
/**
@@ -1042,7 +1058,7 @@ class Delta {
}
/**
- * The possible results of validating analysis results againt a [Delta].
+ * The possible results of validating analysis results against a [Delta].
*/
enum DeltaResult {
/**
@@ -1118,8 +1134,27 @@ class ReentrantSynchronousStream<T> {
* Note that if the [listener] fires a new event, then the [listener] will be
* invoked again before returning from the [add] invocation.
*/
- void listen(void listener(T event)) {
+ ReentrantSynchronousStreamSubscription<T> listen(void listener(T event)) {
listeners.add(listener);
+ return new ReentrantSynchronousStreamSubscription<T>(this, listener);
+ }
+}
+
+/**
+ * A subscription on events from a [ReentrantSynchronousStream].
+ */
+class ReentrantSynchronousStreamSubscription<T> {
+ final ReentrantSynchronousStream<T> _stream;
+ final Function _listener;
+
+ ReentrantSynchronousStreamSubscription(this._stream, this._listener);
+
+ /**
+ * Cancels this subscription.
+ * It will no longer receive events.
+ */
+ void cancel() {
+ _stream.listeners.remove(_listener);
}
}
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/context/context.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698