Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

dbpool.c File Reference

#include "gwlib.h"
#include "dbpool.h"
#include "dbpool_p.h"
#include "dbpool_mysql.c"
#include "dbpool_oracle.c"
#include "dbpool_sqlite.c"
#include "dbpool_sqlite3.c"
#include "dbpool_sdb.c"
#include "dbpool_pgsql.c"

Include dependency graph for dbpool.c:

Include dependency graph

Go to the source code of this file.

Functions

void dbpool_conn_destroy (DBPoolConn *conn)
DBPooldbpool_create (enum db_type db_type, DBConf *conf, unsigned int connections)
void dbpool_destroy (DBPool *p)
unsigned int dbpool_increase (DBPool *p, unsigned int count)
unsigned int dbpool_decrease (DBPool *p, unsigned int c)
long dbpool_conn_count (DBPool *p)
DBPoolConndbpool_conn_consume (DBPool *p)
void dbpool_conn_produce (DBPoolConn *pc)
unsigned int dbpool_check (DBPool *p)
int dbpool_conn_select (DBPoolConn *conn, const Octstr *sql, List *binds, List **result)
int dbpool_conn_update (DBPoolConn *conn, const Octstr *sql, List *binds)


Function Documentation

unsigned int dbpool_check DBPool p  ) 
 

Definition at line 313 of file dbpool.c.

References db_ops::check, DBPoolConn::conn, DBPool::curr_size, DBPool::db_ops, dbpool_conn_destroy(), dbpool_increase(), gw_assert, gwlist_delete(), gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_unlock(), and DBPool::pool.

Referenced by main().

00314 {
00315     long i, len, n = 0, reinit = 0;
00316 
00317     gw_assert(p != NULL && p->pool != NULL && p->db_ops != NULL);
00318 
00319     /*
00320      * First check if db_ops->check function pointer is here.
00321      * NOTE: db_ops->check is optional, so if it is not there, then
00322      * we have nothing todo and we simple return list length.
00323      */
00324     if (p->db_ops->check == NULL)
00325         return gwlist_len(p->pool);
00326 
00327     gwlist_lock(p->pool);
00328     len = gwlist_len(p->pool);
00329     for (i = 0; i < len; i++) {
00330         DBPoolConn *pconn;
00331 
00332         pconn = gwlist_get(p->pool, i);
00333         if (p->db_ops->check(pconn->conn) != 0) {
00334             /* something was wrong, reinitialize the connection */
00335             gwlist_delete(p->pool, i, 1);
00336             dbpool_conn_destroy(pconn);
00337             p->curr_size--;
00338             reinit++;
00339             len--;
00340             i--;
00341         } else {
00342             n++;
00343         }
00344     }
00345     gwlist_unlock(p->pool);
00346 
00347     /* reinitialize brocken connections */
00348     if (reinit > 0)
00349         n += dbpool_increase(p, reinit);
00350 
00351 
00352     return n;
00353 }

Here is the call graph for this function:

DBPoolConn* dbpool_conn_consume DBPool p  ) 
 

Definition at line 249 of file dbpool.c.

References db_ops::check, DBPoolConn::conn, DBPool::curr_size, DBPool::db_ops, dbpool_conn_destroy(), dbpool_increase(), debug(), gw_assert, gwlist_consume(), gwlist_lock(), gwlist_unlock(), gwthread_sleep(), DBPool::max_size, and DBPool::pool.

Referenced by mysql_client_thread(), mysql_select(), mysql_update(), pgsql_select(), pgsql_update(), and sqlite3_client_thread().

00250 {
00251     DBPoolConn *pc;
00252 
00253     gw_assert(p != NULL && p->pool != NULL);
00254     
00255     /* check for max connections and if 0 return NULL */
00256     if (p->max_size < 1)
00257         return NULL;
00258 
00259     /* check if we have any connection */
00260     while (p->curr_size < 1) {
00261         debug("dbpool", 0, "DBPool has no connections, reconnecting up to maximum...");
00262         /* dbpool_increase ensure max_size is not exceeded so don't lock */
00263         dbpool_increase(p, p->max_size - p->curr_size);
00264         if (p->curr_size < 1)
00265             gwthread_sleep(0.1);
00266     }
00267 
00268     /* garantee that you deliver a valid connection to the caller */
00269     while ((pc = gwlist_consume(p->pool)) != NULL) {
00270 
00271         /* 
00272          * XXX check that the connection is still existing.
00273          * Is this a performance bottle-neck?!
00274          */
00275         if (!pc->conn || (p->db_ops->check && p->db_ops->check(pc->conn) != 0)) {
00276             /* something was wrong, reinitialize the connection */
00277             /* lock dbpool for update */
00278             gwlist_lock(p->pool);
00279             dbpool_conn_destroy(pc);
00280             p->curr_size--;
00281             /* unlock dbpool for update */
00282             gwlist_unlock(p->pool);
00283             /*
00284              * maybe not needed, just try to get next connection, but it
00285              * can be dangeros if all connections where broken, then we will
00286              * block here for ever.
00287              */
00288             while (p->curr_size < 1) {
00289                 debug("dbpool", 0, "DBPool has too few connections, reconnecting up to maximum...");
00290                 /* dbpool_increase ensure max_size is not exceeded so don't lock */
00291                 dbpool_increase(p, p->max_size - p->curr_size);
00292                 if (p->curr_size < 1)
00293                     gwthread_sleep(0.1);
00294             }
00295 
00296         } else {
00297             break;
00298         }
00299     }
00300 
00301     return (pc->conn != NULL ? pc : NULL);
00302 }

Here is the call graph for this function:

long dbpool_conn_count DBPool p  ) 
 

Definition at line 241 of file dbpool.c.

References gw_assert, gwlist_len(), and DBPool::pool.

Referenced by dlr_init_mysql(), dlr_init_pgsql(), inc_dec_thread(), and main().

00242 {
00243     gw_assert(p != NULL && p->pool != NULL);
00244 
00245     return gwlist_len(p->pool);
00246 }

Here is the call graph for this function:

void dbpool_conn_destroy DBPoolConn conn  )  [static]
 

Definition at line 82 of file dbpool.c.

References db_ops::close, DBPoolConn::conn, DBPool::db_ops, gw_assert, and DBPoolConn::pool.

Referenced by dbpool_check(), dbpool_conn_consume(), dbpool_decrease(), and dbpool_destroy().

00083 {
00084     gw_assert(conn != NULL);
00085 
00086     if (conn->conn != NULL)
00087         conn->pool->db_ops->close(conn->conn);
00088 
00089     gw_free(conn);
00090 }

void dbpool_conn_produce DBPoolConn pc  ) 
 

Definition at line 305 of file dbpool.c.

References DBPoolConn::conn, gw_assert, gwlist_produce(), DBPoolConn::pool, and DBPool::pool.

Referenced by mysql_client_thread(), mysql_select(), mysql_update(), pgsql_select(), pgsql_update(), and sqlite3_client_thread().

00306 {
00307     gw_assert(pc != NULL && pc->conn != NULL && pc->pool != NULL && pc->pool->pool != NULL);
00308 
00309     gwlist_produce(pc->pool->pool, pc);
00310 }

Here is the call graph for this function:

int dbpool_conn_select DBPoolConn conn,
const Octstr sql,
List binds,
List **  result
 

Definition at line 356 of file dbpool.c.

References DBPoolConn::conn, DBPool::db_ops, DBPoolConn::pool, result, and db_ops::select.

Referenced by pgsql_select().

00357 {
00358     if (sql == NULL || conn == NULL)
00359         return -1;
00360 
00361     if (conn->pool->db_ops->select == NULL)
00362         return -1; /* may be panic here ??? */
00363 
00364     return conn->pool->db_ops->select(conn->conn, sql, binds, result);
00365 }

int dbpool_conn_update DBPoolConn conn,
const Octstr sql,
List binds
 

Definition at line 368 of file dbpool.c.

References DBPoolConn::conn, DBPool::db_ops, DBPoolConn::pool, and db_ops::update.

Referenced by pgsql_update().

00369 {
00370     if (sql == NULL || conn == NULL)
00371         return -1;
00372 
00373     if (conn->pool->db_ops->update == NULL)
00374         return -1; /* may be panic here ??? */
00375 
00376     return conn->pool->db_ops->update(conn->conn, sql, binds);
00377 }

DBPool* dbpool_create enum db_type  db_type,
DBConf conf,
unsigned int  connections
 

Definition at line 97 of file dbpool.c.

References DBPool::conf, DBPool::curr_size, DBPool::db_ops, dbpool_increase(), DBPOOL_MYSQL, DBPOOL_ORACLE, DBPOOL_PGSQL, DBPOOL_SDB, DBPOOL_SQLITE, DBPOOL_SQLITE3, gw_assert, gwlist_add_producer(), gwlist_create, DBPool::max_size, panic, and DBPool::pool.

Referenced by dlr_init_mysql(), dlr_init_pgsql(), and main().

00098 {
00099     DBPool *p;
00100 
00101     if (conf == NULL)
00102         return NULL;
00103 
00104     p = gw_malloc(sizeof(DBPool));
00105     gw_assert(p != NULL);
00106     p->pool = gwlist_create();
00107     gwlist_add_producer(p->pool);
00108     p->max_size = connections;
00109     p->curr_size = 0;
00110     p->conf = conf;
00111     p->db_type = db_type;
00112 
00113     switch(db_type) {
00114 #ifdef HAVE_MYSQL
00115         case DBPOOL_MYSQL:
00116             p->db_ops = &mysql_ops;
00117             break;
00118 #endif
00119 #ifdef HAVE_ORACLE
00120         case DBPOOL_ORACLE:
00121             p->db_ops = &oracle_ops;
00122             break;
00123 #endif
00124 #ifdef HAVE_SQLITE
00125         case DBPOOL_SQLITE:
00126             p->db_ops = &sqlite_ops;
00127             break;
00128 #endif
00129 #ifdef HAVE_SQLITE3
00130         case DBPOOL_SQLITE3:
00131             p->db_ops = &sqlite3_ops;
00132             break;
00133 #endif
00134 #ifdef HAVE_SDB
00135         case DBPOOL_SDB:
00136             p->db_ops = &sdb_ops;
00137             break;
00138 #endif
00139 #ifdef HAVE_PGSQL
00140        case DBPOOL_PGSQL:
00141            p->db_ops = &pgsql_ops;
00142            break;
00143 #endif
00144         default:
00145             panic(0, "Unknown dbpool type defined.");
00146     }
00147 
00148     /*
00149      * XXX what is todo here if not all connections
00150      * where established ???
00151      */
00152     dbpool_increase(p, connections);
00153 
00154     return p;
00155 }

Here is the call graph for this function:

unsigned int dbpool_decrease DBPool p,
unsigned int  c
 

Definition at line 207 of file dbpool.c.

References db_ops::close, DBPool::curr_size, DBPool::db_ops, dbpool_conn_destroy(), gw_assert, gwlist_extract_first(), gwlist_lock(), gwlist_unlock(), and DBPool::pool.

Referenced by inc_dec_thread().

00208 {
00209     unsigned int i;
00210 
00211     gw_assert(p != NULL && p->pool != NULL && p->db_ops != NULL && p->db_ops->close != NULL);
00212 
00213     /* lock dbpool for updates */
00214     gwlist_lock(p->pool);
00215 
00216     /*
00217      * Ensure we don't try to decrease more then available in pool.
00218      */
00219     for (i = 0; i < c; i++) {
00220         DBPoolConn *pc;
00221 
00222         /* gwlist_extract_first doesn't block even if no conn here */
00223         pc = gwlist_extract_first(p->pool);
00224 
00225         /* no conn availible anymore */
00226         if (pc == NULL)
00227             break;
00228 
00229         /* close connections and destroy pool connection */
00230         dbpool_conn_destroy(pc);
00231         p->curr_size--;
00232     }
00233 
00234     /* unlock dbpool for updates */
00235     gwlist_unlock(p->pool);
00236 
00237     return i;
00238 }

Here is the call graph for this function:

void dbpool_destroy DBPool p  ) 
 

Definition at line 158 of file dbpool.c.

References DBPool::conf, db_ops::conf_destroy, DBPool::db_ops, dbpool_conn_destroy(), gw_assert, gwlist_destroy(), gwlist_remove_producer(), and DBPool::pool.

Referenced by dlr_mysql_shutdown(), dlr_pgsql_shutdown(), and main().

00159 {
00160 
00161     if (p == NULL)
00162         return; /* nothing todo here */
00163 
00164     gw_assert(p->pool != NULL && p->db_ops != NULL);
00165 
00166     gwlist_remove_producer(p->pool);
00167     gwlist_destroy(p->pool, (void*) dbpool_conn_destroy);
00168 
00169     p->db_ops->conf_destroy(p->conf);
00170     gw_free(p);
00171 }

Here is the call graph for this function:

unsigned int dbpool_increase DBPool p,
unsigned int  count
 

Definition at line 174 of file dbpool.c.

References DBPool::conf, DBPoolConn::conn, DBPool::curr_size, DBPool::db_ops, gw_assert, gwlist_lock(), gwlist_produce(), gwlist_unlock(), DBPool::max_size, db_ops::open, DBPool::pool, and DBPoolConn::pool.

Referenced by dbpool_check(), dbpool_conn_consume(), dbpool_create(), and inc_dec_thread().

00175 {
00176     unsigned int i, opened = 0;
00177 
00178     gw_assert(p != NULL && p->conf != NULL && p->db_ops != NULL && p->db_ops->open != NULL);
00179 
00180 
00181     /* lock dbpool for updates */
00182     gwlist_lock(p->pool);
00183 
00184     /* ensure we don't increase more items than the max_size border */
00185     for (i=0; i < count && p->curr_size < p->max_size; i++) {
00186         void *conn = p->db_ops->open(p->conf);
00187         if (conn != NULL) {
00188             DBPoolConn *pc = gw_malloc(sizeof(DBPoolConn));
00189             gw_assert(pc != NULL);
00190 
00191             pc->conn = conn;
00192             pc->pool = p;
00193 
00194             p->curr_size++;
00195             opened++;
00196             gwlist_produce(p->pool, pc);
00197         }
00198     }
00199 
00200     /* unlock dbpool for updates */
00201     gwlist_unlock(p->pool);
00202 
00203     return opened;
00204 }

Here is the call graph for this function:

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.