dovecot-2.0: pgsql: Changed the way IO handlers are added/removed.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Aug 3 17:46:04 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/e31570bccb92
changeset: 11921:e31570bccb92
user: Timo Sirainen <tss at iki.fi>
date: Tue Aug 03 15:42:34 2010 +0100
description:
pgsql: Changed the way IO handlers are added/removed.
Remove IO handlers before calling any pgsql functions, so that if it closes
the socket, we don't later try to remove IO for already closed socket.
diffstat:
src/lib-sql/driver-pgsql.c | 70 ++++++++++++++++++-----------------
1 files changed, 36 insertions(+), 34 deletions(-)
diffs (165 lines):
diff -r 7c4b4f07d64e -r e31570bccb92 src/lib-sql/driver-pgsql.c
--- a/src/lib-sql/driver-pgsql.c Tue Aug 03 13:10:19 2010 +0100
+++ b/src/lib-sql/driver-pgsql.c Tue Aug 03 15:42:34 2010 +0100
@@ -84,6 +84,14 @@
current_ioloop = db->ioloop;
}
+static void driver_pgsql_stop_io(struct pgsql_db *db)
+{
+ if (db->io != NULL) {
+ io_remove(&db->io);
+ db->io_dir = 0;
+ }
+}
+
static void driver_pgsql_close(struct pgsql_db *db)
{
db->io_dir = 0;
@@ -92,11 +100,7 @@
PQfinish(db->pg);
db->pg = NULL;
- if (db->io != NULL) {
- /* The fd may be closed before call to PQfinish() already,
- so use io_remove_closed(). */
- io_remove_closed(&db->io);
- }
+ driver_pgsql_stop_io(db);
if (db->to_connect != NULL)
timeout_remove(&db->to_connect);
@@ -128,6 +132,8 @@
enum io_condition io_dir = 0;
int ret;
+ driver_pgsql_stop_io(db);
+
while ((ret = PQconnectPoll(db->pg)) == PGRES_POLLING_ACTIVE)
;
@@ -147,11 +153,8 @@
return;
}
- if (db->io_dir != io_dir) {
- if (db->io != NULL)
- io_remove(&db->io);
- db->io = io_dir == 0 ? NULL :
- io_add(PQsocket(db->pg), io_dir, connect_callback, db);
+ if (io_dir != 0) {
+ db->io = io_add(PQsocket(db->pg), io_dir, connect_callback, db);
db->io_dir = io_dir;
}
@@ -265,9 +268,15 @@
{
PGresult *pgres;
+ driver_pgsql_stop_io(db);
+
while (PQconsumeInput(db->pg)) {
- if (PQisBusy(db->pg))
+ if (PQisBusy(db->pg)) {
+ db->io = io_add(PQsocket(db->pg), IO_READ,
+ consume_results, db);
+ db->io_dir = IO_READ;
return;
+ }
pgres = PQgetResult(db->pg);
if (pgres == NULL)
@@ -275,13 +284,10 @@
PQclear(pgres);
}
- if (PQstatus(db->pg) == CONNECTION_BAD) {
- io_remove_closed(&db->io);
+ if (PQstatus(db->pg) == CONNECTION_BAD)
driver_pgsql_close(db);
- } else {
- io_remove(&db->io);
+ else
driver_pgsql_set_idle(db);
- }
}
static void driver_pgsql_result_free(struct sql_result *_result)
@@ -313,9 +319,6 @@
if (success) {
/* we'll have to read the rest of the results as well */
i_assert(db->io == NULL);
- db->io = io_add(PQsocket(db->pg), IO_READ,
- consume_results, db);
- db->io_dir = IO_READ;
consume_results(db);
} else {
driver_pgsql_set_idle(db);
@@ -339,6 +342,7 @@
struct pgsql_db *db = (struct pgsql_db *)result->api.db;
bool free_result = TRUE;
+ i_assert(db->io == NULL);
timeout_remove(&result->to);
/* if connection to server was lost, we don't yet see that the
@@ -371,23 +375,20 @@
{
struct pgsql_db *db = (struct pgsql_db *)result->api.db;
+ driver_pgsql_stop_io(db);
+
if (!PQconsumeInput(db->pg)) {
result_finish(result);
return;
}
if (PQisBusy(db->pg)) {
- if (db->io == NULL) {
- db->io = io_add(PQsocket(db->pg), IO_READ,
- get_result, result);
- db->io_dir = IO_READ;
- }
+ db->io = io_add(PQsocket(db->pg), IO_READ,
+ get_result, result);
+ db->io_dir = IO_READ;
return;
}
- if (db->io != NULL)
- io_remove(&db->io);
-
result->pgres = PQgetResult(db->pg);
result_finish(result);
}
@@ -397,11 +398,15 @@
struct pgsql_db *db = (struct pgsql_db *)result->api.db;
int ret;
+ driver_pgsql_stop_io(db);
+
ret = PQflush(db->pg);
- if (ret > 0)
+ if (ret > 0) {
+ db->io = io_add(PQsocket(db->pg), IO_WRITE,
+ flush_callback, result);
+ db->io_dir = IO_WRITE;
return;
-
- io_remove(&db->io);
+ }
if (ret < 0) {
result_finish(result);
@@ -565,10 +570,7 @@
if (db->sync_result == NULL)
io_loop_run(db->ioloop);
- if (db->io != NULL) {
- i_assert(db->fatal_error);
- io_remove_closed(&db->io);
- }
+ i_assert(db->io == NULL);
result = db->sync_result;
if (result == &sql_not_connected_result) {
More information about the dovecot-cvs
mailing list