OLD | NEW |
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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 | 7 |
8 import 'package:async/async.dart'; | 8 import 'package:async/async.dart'; |
9 import 'package:stack_trace/stack_trace.dart'; | 9 import 'package:stack_trace/stack_trace.dart'; |
10 | 10 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 _requestedResources.add(completer); | 99 _requestedResources.add(completer); |
100 _resetTimer(); | 100 _resetTimer(); |
101 return completer.future; | 101 return completer.future; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 /// Requests a resource for the duration of [callback], which may return a | 105 /// Requests a resource for the duration of [callback], which may return a |
106 /// Future. | 106 /// Future. |
107 /// | 107 /// |
108 /// The return value of [callback] is piped to the returned Future. | 108 /// The return value of [callback] is piped to the returned Future. |
109 Future withResource(callback()) { | 109 Future/*<T>*/ withResource/*<T>*/(/*=T*/ callback()) async { |
110 if (isClosed) { | 110 if (isClosed) { |
111 throw new StateError( | 111 throw new StateError( |
112 "withResource() may not be called on a closed Pool."); | 112 "withResource() may not be called on a closed Pool."); |
113 } | 113 } |
114 | 114 |
115 // TODO(nweiz): Use async/await when sdk#23497 is fixed. | 115 var resource = await request(); |
116 return request().then((resource) { | 116 try { |
117 return new Future.sync(callback).whenComplete(resource.release); | 117 return await callback(); |
118 }); | 118 } finally { |
| 119 resource.release(); |
| 120 } |
119 } | 121 } |
120 | 122 |
121 /// Closes the pool so that no more resources are requested. | 123 /// Closes the pool so that no more resources are requested. |
122 /// | 124 /// |
123 /// Existing resource requests remain unchanged. | 125 /// Existing resource requests remain unchanged. |
124 /// | 126 /// |
125 /// Any resources that are marked as releasable using | 127 /// Any resources that are marked as releasable using |
126 /// [PoolResource.allowRelease] are released immediately. Once all resources | 128 /// [PoolResource.allowRelease] are released immediately. Once all resources |
127 /// have been released and any `onRelease` callbacks have completed, the | 129 /// have been released and any `onRelease` callbacks have completed, the |
128 /// returned future completes successfully. If any `onRelease` callback throws | 130 /// returned future completes successfully. If any `onRelease` callback throws |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 /// | 184 /// |
183 /// Futures returned by [_runOnRelease] always complete in the order they were | 185 /// Futures returned by [_runOnRelease] always complete in the order they were |
184 /// created, even if earlier [onRelease] callbacks take longer to run. | 186 /// created, even if earlier [onRelease] callbacks take longer to run. |
185 Future<PoolResource> _runOnRelease(onRelease()) { | 187 Future<PoolResource> _runOnRelease(onRelease()) { |
186 new Future.sync(onRelease).then((value) { | 188 new Future.sync(onRelease).then((value) { |
187 _onReleaseCompleters.removeFirst().complete(new PoolResource._(this)); | 189 _onReleaseCompleters.removeFirst().complete(new PoolResource._(this)); |
188 }).catchError((error, stackTrace) { | 190 }).catchError((error, stackTrace) { |
189 _onReleaseCompleters.removeFirst().completeError(error, stackTrace); | 191 _onReleaseCompleters.removeFirst().completeError(error, stackTrace); |
190 }); | 192 }); |
191 | 193 |
192 var completer = new Completer.sync(); | 194 var completer = new Completer<PoolResource>.sync(); |
193 _onReleaseCompleters.add(completer); | 195 _onReleaseCompleters.add(completer); |
194 return completer.future; | 196 return completer.future; |
195 } | 197 } |
196 | 198 |
197 /// A resource has been requested, allocated, or released. | 199 /// A resource has been requested, allocated, or released. |
198 void _resetTimer() { | 200 void _resetTimer() { |
199 if (_timer == null) return; | 201 if (_timer == null) return; |
200 | 202 |
201 if (_requestedResources.isEmpty) { | 203 if (_requestedResources.isEmpty) { |
202 _timer.cancel(); | 204 _timer.cancel(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 /// produce additional information later on. For example, an isolate's task | 257 /// produce additional information later on. For example, an isolate's task |
256 /// may be complete, but it could still emit asynchronous errors. | 258 /// may be complete, but it could still emit asynchronous errors. |
257 void allowRelease(onRelease()) { | 259 void allowRelease(onRelease()) { |
258 if (_released) { | 260 if (_released) { |
259 throw new StateError("A PoolResource may only be released once."); | 261 throw new StateError("A PoolResource may only be released once."); |
260 } | 262 } |
261 _released = true; | 263 _released = true; |
262 _pool._onResourceReleaseAllowed(onRelease); | 264 _pool._onResourceReleaseAllowed(onRelease); |
263 } | 265 } |
264 } | 266 } |
OLD | NEW |