Chromium Code Reviews| 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 library pool; | 5 library pool; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:stack_trace/stack_trace.dart'; | 10 import 'package:stack_trace/stack_trace.dart'; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 /// The timeout timer. | 33 /// The timeout timer. |
| 34 /// | 34 /// |
| 35 /// If [_timeout] isn't null, this timer is set as soon as the resource limit | 35 /// If [_timeout] isn't null, this timer is set as soon as the resource limit |
| 36 /// is reached and is reset every time an resource is released or a new | 36 /// is reached and is reset every time an resource is released or a new |
| 37 /// resource is requested. If it fires, that indicates that the caller became | 37 /// resource is requested. If it fires, that indicates that the caller became |
| 38 /// deadlocked, likely due to files waiting for additional files to be read | 38 /// deadlocked, likely due to files waiting for additional files to be read |
| 39 /// before they could be closed. | 39 /// before they could be closed. |
| 40 Timer _timer; | 40 Timer _timer; |
| 41 | 41 |
| 42 /// The amount of time to wait before timing out the pending resources. | 42 /// The amount of time to wait before timing out the pending resources. |
| 43 Duration _timeout; | 43 final Duration _timeout; |
| 44 | 44 |
| 45 /// Creates a new pool with the given limit on how many resources may be | 45 /// Creates a new pool with the given limit on how many resources may be |
| 46 /// allocated at once. | 46 /// allocated at once. |
| 47 /// | 47 /// |
| 48 /// If [timeout] is passed, then if that much time passes without any activity | 48 /// If [timeout] is passed, then if that much time passes without any activity |
| 49 /// all pending [request] futures will throw an exception. This is indented | 49 /// all pending [request] futures will throw a [TimeoutException]. This is |
| 50 /// to avoid deadlocks. | 50 /// indented to avoid deadlocks. |
|
Alan Knight
2014/07/24 20:28:15
should be "intended"?
nweiz
2014/07/24 20:29:20
Yep!
| |
| 51 Pool(this._maxAllocatedResources, {Duration timeout}) | 51 Pool(this._maxAllocatedResources, {Duration timeout}) |
| 52 : _timeout = timeout; | 52 : _timeout = timeout; |
| 53 | 53 |
| 54 /// Request a [PoolResource]. | 54 /// Request a [PoolResource]. |
| 55 /// | 55 /// |
| 56 /// If the maximum number of resources is already allocated, this will delay | 56 /// If the maximum number of resources is already allocated, this will delay |
| 57 /// until one of them is released. | 57 /// until one of them is released. |
| 58 Future<PoolResource> request() { | 58 Future<PoolResource> request() { |
| 59 if (_allocatedResources < _maxAllocatedResources) { | 59 if (_allocatedResources < _maxAllocatedResources) { |
| 60 _allocatedResources++; | 60 _allocatedResources++; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 _timer = null; | 99 _timer = null; |
| 100 } else { | 100 } else { |
| 101 _timer = new Timer(_timeout, _onTimeout); | 101 _timer = new Timer(_timeout, _onTimeout); |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 /// Handles [_timer] timing out by causing all pending resource completers to | 105 /// Handles [_timer] timing out by causing all pending resource completers to |
| 106 /// emit exceptions. | 106 /// emit exceptions. |
| 107 void _onTimeout() { | 107 void _onTimeout() { |
| 108 for (var completer in _requestedResources) { | 108 for (var completer in _requestedResources) { |
| 109 completer.completeError("Pool deadlock: all resources have been " | 109 completer.completeError( |
| 110 "allocated for too long.", new Chain.current()); | 110 new TimeoutException("Pool deadlock: all resources have been " |
| 111 "allocated for too long.", | |
| 112 _timeout), | |
| 113 new Chain.current()); | |
| 111 } | 114 } |
| 112 _requestedResources.clear(); | 115 _requestedResources.clear(); |
| 113 _timer = null; | 116 _timer = null; |
| 114 } | 117 } |
| 115 } | 118 } |
| 116 | 119 |
| 117 /// A member of a [Pool]. | 120 /// A member of a [Pool]. |
| 118 /// | 121 /// |
| 119 /// A [PoolResource] is a token that indicates that a resource is allocated. | 122 /// A [PoolResource] is a token that indicates that a resource is allocated. |
| 120 /// When the associated resource is released, the user should call [release]. | 123 /// When the associated resource is released, the user should call [release]. |
| 121 class PoolResource { | 124 class PoolResource { |
| 122 final Pool _pool; | 125 final Pool _pool; |
| 123 | 126 |
| 124 /// Whether [this] has been released yet. | 127 /// Whether [this] has been released yet. |
| 125 bool _released = false; | 128 bool _released = false; |
| 126 | 129 |
| 127 PoolResource._(this._pool); | 130 PoolResource._(this._pool); |
| 128 | 131 |
| 129 /// Tells the parent [Pool] that the resource associated with this resource is | 132 /// Tells the parent [Pool] that the resource associated with this resource is |
| 130 /// no longer allocated, and that a new [PoolResource] may be allocated. | 133 /// no longer allocated, and that a new [PoolResource] may be allocated. |
| 131 void release() { | 134 void release() { |
| 132 if (_released) { | 135 if (_released) { |
| 133 throw new StateError("A PoolResource may only be released once."); | 136 throw new StateError("A PoolResource may only be released once."); |
| 134 } | 137 } |
| 135 _released = true; | 138 _released = true; |
| 136 _pool._onResourceReleased(); | 139 _pool._onResourceReleased(); |
| 137 } | 140 } |
| 138 } | 141 } |
| 139 | 142 |
| OLD | NEW |