Skip to content

Commit 761c378

Browse files
committed
Retrieving the async cursor moved out of conn_poll() body
1 parent e864050 commit 761c378

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

psycopg/connection_int.c

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,35 @@ _conn_poll_setup_async(connectionObject *self)
10421042
}
10431043

10441044

1045+
static cursorObject *
1046+
_conn_get_async_cursor(connectionObject *self) {
1047+
PyObject *py_curs;
1048+
1049+
if (!(self->async_cursor)) {
1050+
PyErr_SetString(PyExc_SystemError,
1051+
"unexpectedly, there's no async cursor here");
1052+
goto error;
1053+
}
1054+
1055+
if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
1056+
PyErr_SetString(PyExc_SystemError,
1057+
"got null dereferencing cursor weakref");
1058+
goto error;
1059+
}
1060+
if (Py_None == py_curs) {
1061+
PyErr_SetString(InterfaceError,
1062+
"the asynchronous cursor has disappeared");
1063+
goto error;
1064+
}
1065+
1066+
Py_INCREF(py_curs);
1067+
return (cursorObject *)py_curs;
1068+
1069+
error:
1070+
pq_clear_async(self);
1071+
return NULL;
1072+
}
1073+
10451074
/* conn_poll - Main polling switch
10461075
*
10471076
* The function is called in all the states and connection types and invokes
@@ -1056,50 +1085,40 @@ conn_poll(connectionObject *self)
10561085

10571086
switch (self->status) {
10581087
case CONN_STATUS_SETUP:
1059-
Dprintf("conn_poll: status -> CONN_STATUS_CONNECTING");
1088+
Dprintf("conn_poll: status -> CONN_STATUS_SETUP");
10601089
self->status = CONN_STATUS_CONNECTING;
10611090
res = PSYCO_POLL_WRITE;
10621091
break;
10631092

10641093
case CONN_STATUS_CONNECTING:
1094+
Dprintf("conn_poll: status -> CONN_STATUS_CONNECTING");
10651095
res = _conn_poll_connecting(self);
10661096
if (res == PSYCO_POLL_OK && self->async) {
10671097
res = _conn_poll_setup_async(self);
10681098
}
10691099
break;
10701100

10711101
case CONN_STATUS_DATESTYLE:
1102+
Dprintf("conn_poll: status -> CONN_STATUS_DATESTYLE");
10721103
res = _conn_poll_setup_async(self);
10731104
break;
10741105

10751106
case CONN_STATUS_READY:
10761107
case CONN_STATUS_BEGIN:
10771108
case CONN_STATUS_PREPARED:
1109+
Dprintf("conn_poll: status -> CONN_STATUS_*");
10781110
res = _conn_poll_query(self);
10791111

1080-
if (res == PSYCO_POLL_OK && self->async && self->async_cursor) {
1112+
if (res == PSYCO_POLL_OK && self->async) {
1113+
cursorObject *curs;
1114+
10811115
/* An async query has just finished: parse the tuple in the
10821116
* target cursor. */
1083-
cursorObject *curs;
1084-
PyObject *py_curs;
1085-
if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
1086-
/* It shouldn't happen but consider it to avoid dereferencing
1087-
* a null pointer below. */
1088-
pq_clear_async(self);
1089-
PyErr_SetString(PyExc_SystemError,
1090-
"got null dereferencing cursor weakref");
1091-
res = PSYCO_POLL_ERROR;
1092-
break;
1093-
}
1094-
if (Py_None == py_curs) {
1095-
pq_clear_async(self);
1096-
PyErr_SetString(InterfaceError,
1097-
"the asynchronous cursor has disappeared");
1117+
if (!(curs = _conn_get_async_cursor(self))) {
10981118
res = PSYCO_POLL_ERROR;
10991119
break;
11001120
}
11011121

1102-
curs = (cursorObject *)py_curs;
11031122
CLEARPGRES(curs->pgres);
11041123
curs->pgres = pq_get_last_result(self);
11051124

@@ -1111,6 +1130,7 @@ conn_poll(connectionObject *self)
11111130
}
11121131

11131132
/* We have finished with our async_cursor */
1133+
Py_DECREF(curs);
11141134
Py_CLEAR(self->async_cursor);
11151135
}
11161136
break;
@@ -1120,6 +1140,7 @@ conn_poll(connectionObject *self)
11201140
res = PSYCO_POLL_ERROR;
11211141
}
11221142

1143+
Dprintf("conn_poll: returning %d", res);
11231144
return res;
11241145
}
11251146

0 commit comments

Comments
 (0)