1
- use super :: inner:: { DecrementSizeGuard , SharedPool } ;
2
- use crate :: connection:: Connection ;
3
- use crate :: database:: Database ;
4
- use crate :: error:: Error ;
5
- use sqlx_rt:: spawn;
6
1
use std:: fmt:: { self , Debug , Formatter } ;
7
2
use std:: ops:: { Deref , DerefMut } ;
8
3
use std:: sync:: Arc ;
9
4
use std:: time:: Instant ;
10
5
6
+ use futures_intrusive:: sync:: SemaphoreReleaser ;
7
+
8
+ use crate :: connection:: Connection ;
9
+ use crate :: database:: Database ;
10
+ use crate :: error:: Error ;
11
+
12
+ use super :: inner:: { DecrementSizeGuard , SharedPool } ;
13
+
11
14
/// A connection managed by a [`Pool`][crate::pool::Pool].
12
15
///
13
16
/// Will be returned to the pool on-drop.
@@ -28,8 +31,8 @@ pub(super) struct Idle<DB: Database> {
28
31
29
32
/// RAII wrapper for connections being handled by functions that may drop them
30
33
pub ( super ) struct Floating < ' p , C > {
31
- inner : C ,
32
- guard : DecrementSizeGuard < ' p > ,
34
+ pub ( super ) inner : C ,
35
+ pub ( super ) guard : DecrementSizeGuard < ' p > ,
33
36
}
34
37
35
38
const DEREF_ERR : & str = "(bug) connection already released to pool" ;
@@ -71,7 +74,7 @@ impl<DB: Database> Drop for PoolConnection<DB> {
71
74
fn drop ( & mut self ) {
72
75
if let Some ( live) = self . live . take ( ) {
73
76
let pool = self . pool . clone ( ) ;
74
- spawn ( async move {
77
+ sqlx_rt :: spawn ( async move {
75
78
let mut floating = live. float ( & pool) ;
76
79
77
80
// test the connection on-release to ensure it is still viable
@@ -102,7 +105,8 @@ impl<DB: Database> Live<DB> {
102
105
pub fn float ( self , pool : & SharedPool < DB > ) -> Floating < ' _ , Self > {
103
106
Floating {
104
107
inner : self ,
105
- guard : DecrementSizeGuard :: new ( pool) ,
108
+ // create a new guard from a previously leaked permit
109
+ guard : DecrementSizeGuard :: new_permit ( pool) ,
106
110
}
107
111
}
108
112
@@ -161,6 +165,11 @@ impl<'s, DB: Database> Floating<'s, Live<DB>> {
161
165
}
162
166
}
163
167
168
+ pub async fn close ( self ) -> Result < ( ) , Error > {
169
+ // `guard` is dropped as intended
170
+ self . inner . raw . close ( ) . await
171
+ }
172
+
164
173
pub fn detach ( self ) -> DB :: Connection {
165
174
self . inner . raw
166
175
}
@@ -174,10 +183,14 @@ impl<'s, DB: Database> Floating<'s, Live<DB>> {
174
183
}
175
184
176
185
impl < ' s , DB : Database > Floating < ' s , Idle < DB > > {
177
- pub fn from_idle ( idle : Idle < DB > , pool : & ' s SharedPool < DB > ) -> Self {
186
+ pub fn from_idle (
187
+ idle : Idle < DB > ,
188
+ pool : & ' s SharedPool < DB > ,
189
+ permit : SemaphoreReleaser < ' s > ,
190
+ ) -> Self {
178
191
Self {
179
192
inner : idle,
180
- guard : DecrementSizeGuard :: new ( pool) ,
193
+ guard : DecrementSizeGuard :: from_permit ( pool, permit ) ,
181
194
}
182
195
}
183
196
@@ -192,9 +205,12 @@ impl<'s, DB: Database> Floating<'s, Idle<DB>> {
192
205
}
193
206
}
194
207
195
- pub async fn close ( self ) -> Result < ( ) , Error > {
208
+ pub async fn close ( self ) -> DecrementSizeGuard < ' s > {
196
209
// `guard` is dropped as intended
197
- self . inner . live . raw . close ( ) . await
210
+ if let Err ( e) = self . inner . live . raw . close ( ) . await {
211
+ log:: debug!( "error occurred while closing the pool connection: {}" , e) ;
212
+ }
213
+ self . guard
198
214
}
199
215
}
200
216
0 commit comments