11//! A simple connection pool
22
3- use std:: cell :: RefCell ;
4- use sync:: MutexArc ;
3+ use std:: cast ;
4+ use sync:: { Arc , Mutex } ;
55
66use { PostgresNotifications ,
77 PostgresCancelData ,
@@ -15,14 +15,28 @@ use types::ToSql;
1515struct InnerConnectionPool {
1616 url : ~str ,
1717 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+ }
1933}
2034
2135impl InnerConnectionPool {
2236 fn new_connection ( & mut self ) -> Option < PostgresConnectError > {
2337 match PostgresConnection :: try_connect ( self . url , & self . ssl ) {
2438 Ok ( conn) => {
25- self . pool . push ( conn) ;
39+ unsafe { self . pool . push ( cast :: transmute ( ~ conn) ) } ;
2640 None
2741 }
2842 Err ( err) => Some ( err)
@@ -51,7 +65,7 @@ impl InnerConnectionPool {
5165/// ```
5266#[ deriving( Clone ) ]
5367pub struct PostgresConnectionPool {
54- priv pool : MutexArc < InnerConnectionPool >
68+ priv pool : Arc < Mutex < InnerConnectionPool > >
5569}
5670
5771impl PostgresConnectionPool {
@@ -64,7 +78,7 @@ impl PostgresConnectionPool {
6478 let mut pool = InnerConnectionPool {
6579 url : url. to_owned ( ) ,
6680 ssl : ssl,
67- pool : ~ [ ] ,
81+ pool : Vec :: new ( ) ,
6882 } ;
6983
7084 for _ in range ( 0 , pool_size) {
@@ -75,7 +89,7 @@ impl PostgresConnectionPool {
7589 }
7690
7791 Ok ( PostgresConnectionPool {
78- pool : MutexArc :: new ( pool)
92+ pool : Arc :: new ( Mutex :: new ( pool) )
7993 } )
8094 }
8195
@@ -96,17 +110,15 @@ impl PostgresConnectionPool {
96110 ///
97111 /// If all connections are in use, blocks until one becomes available.
98112 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 ( ) ;
103114
104- pool. pool . pop ( ) . unwrap ( )
105- } ) ;
115+ while pool. pool . is_empty ( ) {
116+ pool. cond . wait ( ) ;
117+ }
106118
107119 PooledPostgresConnection {
108120 pool : self . clone ( ) ,
109- conn : Some ( conn )
121+ conn : Some ( unsafe { cast :: transmute ( pool . pool . pop ( ) . unwrap ( ) ) } )
110122 }
111123 }
112124}
@@ -118,15 +130,13 @@ impl PostgresConnectionPool {
118130pub struct PooledPostgresConnection {
119131 priv pool : PostgresConnectionPool ,
120132 // TODO remove the Option wrapper when drop takes self by value
121- priv conn : Option < PostgresConnection >
133+ priv conn : Option < ~ PostgresConnection >
122134}
123135
124136impl Drop for PooledPostgresConnection {
125137 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) ;
130140 }
131141}
132142
0 commit comments