@@ -2,10 +2,10 @@ import 'dart:async';
2
2
3
3
import 'package:collection/collection.dart' ;
4
4
import 'package:pool/pool.dart' as pool;
5
- import 'package:postgres/src/v3/resolved_settings.dart' ;
6
5
7
6
import '../../postgres.dart' ;
8
7
import '../v3/connection.dart' ;
8
+ import '../v3/resolved_settings.dart' ;
9
9
10
10
EndpointSelector roundRobinSelector (List <Endpoint > endpoints) {
11
11
int nextIndex = 0 ;
@@ -26,6 +26,10 @@ class PoolImplementation<L> implements Pool<L> {
26
26
_maxConnectionCount,
27
27
timeout: _settings.connectTimeout,
28
28
);
29
+ late final _connectLock = pool.Pool (
30
+ 1 ,
31
+ timeout: _settings.connectTimeout,
32
+ );
29
33
30
34
PoolImplementation (this ._selector, PoolSettings ? settings)
31
35
: _settings = ResolvedPoolSettings (settings);
@@ -173,32 +177,34 @@ class PoolImplementation<L> implements Pool<L> {
173
177
return oldc;
174
178
}
175
179
176
- while (_connections.length == _maxConnectionCount) {
177
- final candidates =
178
- _connections.where ((c) => c._isInUse == false ).toList ();
179
- if (candidates.isEmpty) {
180
- throw StateError ('The pool should not be in this state.' );
180
+ return await _connectLock.withResource (() async {
181
+ while (_connections.length >= _maxConnectionCount) {
182
+ final candidates =
183
+ _connections.where ((c) => c._isInUse == false ).toList ();
184
+ if (candidates.isEmpty) {
185
+ throw StateError ('The pool should not be in this state.' );
186
+ }
187
+ final selected = candidates.reduce (
188
+ (a, b) => a._lastReturned.isBefore (b._lastReturned) ? a : b);
189
+ await selected._dispose ();
181
190
}
182
- final selected = candidates
183
- .reduce ((a, b) => a._lastReturned.isBefore (b._lastReturned) ? a : b);
184
- await selected._dispose ();
185
- }
186
191
187
- final newc = _PoolConnection (
188
- this ,
189
- endpoint,
190
- settings,
191
- await PgConnectionImplementation .connect (
192
+ final newc = _PoolConnection (
193
+ this ,
192
194
endpoint,
193
- connectionSettings: settings,
194
- ),
195
- );
196
- newc._isInUse = true ;
197
- // NOTE: It is important to update _connections list after the isInUse
198
- // flag is set, otherwise race conditions may create conflicts or
199
- // pool close may miss the connection.
200
- _connections.add (newc);
201
- return newc;
195
+ settings,
196
+ await PgConnectionImplementation .connect (
197
+ endpoint,
198
+ connectionSettings: settings,
199
+ ),
200
+ );
201
+ newc._isInUse = true ;
202
+ // NOTE: It is important to update _connections list after the isInUse
203
+ // flag is set, otherwise race conditions may create conflicts or
204
+ // pool close may miss the connection.
205
+ _connections.add (newc);
206
+ return newc;
207
+ });
202
208
}
203
209
}
204
210
0 commit comments