1
1
//! A simple connection pool
2
2
3
- use std:: cell :: RefCell ;
4
- use sync:: MutexArc ;
3
+ use std:: cast ;
4
+ use sync:: { Arc , Mutex } ;
5
5
6
6
use { PostgresNotifications ,
7
7
PostgresCancelData ,
@@ -15,14 +15,28 @@ use types::ToSql;
15
15
struct InnerConnectionPool {
16
16
url : ~str ,
17
17
ssl : SslMode ,
18
- pool : ~[ PostgresConnection ] ,
18
+ // Actually Vec<~PostgresConnection>
19
+ pool : Vec < * ( ) > ,
20
+ }
21
+
22
+ impl Drop for InnerConnectionPool {
23
+ fn drop ( & mut self ) {
24
+ loop {
25
+ match self . pool . pop ( ) {
26
+ Some ( conn) => unsafe {
27
+ drop ( cast:: transmute :: < * ( ) , ~PostgresConnection > ( conn) ) ;
28
+ } ,
29
+ None => break
30
+ }
31
+ }
32
+ }
19
33
}
20
34
21
35
impl InnerConnectionPool {
22
36
fn new_connection ( & mut self ) -> Option < PostgresConnectError > {
23
37
match PostgresConnection :: try_connect ( self . url , & self . ssl ) {
24
38
Ok ( conn) => {
25
- self . pool . push ( conn) ;
39
+ unsafe { self . pool . push ( cast :: transmute ( ~ conn) ) } ;
26
40
None
27
41
}
28
42
Err ( err) => Some ( err)
@@ -51,7 +65,7 @@ impl InnerConnectionPool {
51
65
/// ```
52
66
#[ deriving( Clone ) ]
53
67
pub struct PostgresConnectionPool {
54
- priv pool : MutexArc < InnerConnectionPool >
68
+ priv pool : Arc < Mutex < InnerConnectionPool > >
55
69
}
56
70
57
71
impl PostgresConnectionPool {
@@ -64,7 +78,7 @@ impl PostgresConnectionPool {
64
78
let mut pool = InnerConnectionPool {
65
79
url : url. to_owned ( ) ,
66
80
ssl : ssl,
67
- pool : ~ [ ] ,
81
+ pool : Vec :: new ( ) ,
68
82
} ;
69
83
70
84
for _ in range ( 0 , pool_size) {
@@ -75,7 +89,7 @@ impl PostgresConnectionPool {
75
89
}
76
90
77
91
Ok ( PostgresConnectionPool {
78
- pool : MutexArc :: new ( pool)
92
+ pool : Arc :: new ( Mutex :: new ( pool) )
79
93
} )
80
94
}
81
95
@@ -96,17 +110,15 @@ impl PostgresConnectionPool {
96
110
///
97
111
/// If all connections are in use, blocks until one becomes available.
98
112
pub fn get_connection ( & self ) -> PooledPostgresConnection {
99
- let conn = self . pool . access_cond ( |pool, cvar| {
100
- while pool. pool . is_empty ( ) {
101
- cvar. wait ( ) ;
102
- }
113
+ let mut pool = self . pool . lock ( ) ;
103
114
104
- pool. pool . pop ( ) . unwrap ( )
105
- } ) ;
115
+ while pool. pool . is_empty ( ) {
116
+ pool. cond . wait ( ) ;
117
+ }
106
118
107
119
PooledPostgresConnection {
108
120
pool : self . clone ( ) ,
109
- conn : Some ( conn )
121
+ conn : Some ( unsafe { cast :: transmute ( pool . pool . pop ( ) . unwrap ( ) ) } )
110
122
}
111
123
}
112
124
}
@@ -118,15 +130,13 @@ impl PostgresConnectionPool {
118
130
pub struct PooledPostgresConnection {
119
131
priv pool : PostgresConnectionPool ,
120
132
// TODO remove the Option wrapper when drop takes self by value
121
- priv conn : Option < PostgresConnection >
133
+ priv conn : Option < ~ PostgresConnection >
122
134
}
123
135
124
136
impl Drop for PooledPostgresConnection {
125
137
fn drop ( & mut self ) {
126
- let conn = RefCell :: new ( self . conn . take ( ) ) ;
127
- self . pool . pool . access ( |pool| {
128
- pool. pool . push ( conn. borrow_mut ( ) . take_unwrap ( ) ) ;
129
- } )
138
+ let conn = unsafe { cast:: transmute ( self . conn . take_unwrap ( ) ) } ;
139
+ self . pool . pool . lock ( ) . pool . push ( conn) ;
130
140
}
131
141
}
132
142
0 commit comments