diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index d92d53f7..2f2a48d6 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -939,21 +939,30 @@ conn_tpc_command(connectionObject *self, const char *cmd, XidObject *xid) { PGresult *pgres = NULL; char *error = NULL; - int rv; + char *tid = NULL; + int rv = -1; Dprintf("conn_tpc_command: %s", cmd); + /* convert the xid into PostgreSQL transaction id while keeping the GIL */ + if (!(tid = xid_get_tid(xid))) { goto exit; } + Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&self->lock); - rv = pq_tpc_command_locked(self, cmd, xid, &pgres, &error, &_save); + if (0 > (rv = pq_tpc_command_locked(self, cmd, tid, + &pgres, &error, &_save))) { + pthread_mutex_unlock(&self->lock); + Py_BLOCK_THREADS; + pq_complete_error(self, &pgres, &error); + goto exit; + } pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; - if (rv < 0) { - pq_complete_error(self, &pgres, &error); - } +exit: + PyMem_Free(tid); return rv; } diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index 37d52791..3977f31d 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -617,19 +617,17 @@ pq_reset(connectionObject *conn) * holding the global interpreter lock. */ int -pq_tpc_command_locked(connectionObject *conn, const char *cmd, XidObject *xid, - PGresult **pgres, char **error, - PyThreadState **tstate) +pq_tpc_command_locked(connectionObject *conn, const char *cmd, const char *tid, + PGresult **pgres, char **error, PyThreadState **tstate) { int rv = -1; - char *tid = NULL, *etid = NULL, *buf = NULL; + char *etid = NULL, *buf = NULL; Py_ssize_t buflen; Dprintf("_pq_tpc_command: pgconn = %p, command = %s", conn->pgconn, cmd); /* convert the xid into the postgres transaction_id and quote it. */ - if (!(tid = xid_get_tid(xid))) { goto exit; } if (!(etid = psycopg_escape_string((PyObject *)conn, tid, 0, NULL, NULL))) { goto exit; } @@ -647,7 +645,6 @@ pq_tpc_command_locked(connectionObject *conn, const char *cmd, XidObject *xid, exit: PyMem_Free(buf); PyMem_Free(etid); - PyMem_Free(tid); return rv; } diff --git a/psycopg/pqpath.h b/psycopg/pqpath.h index 5f56efa4..51a640dc 100644 --- a/psycopg/pqpath.h +++ b/psycopg/pqpath.h @@ -47,7 +47,7 @@ HIDDEN int pq_abort_locked(connectionObject *conn, PGresult **pgres, HIDDEN int pq_abort(connectionObject *conn); HIDDEN int pq_reset(connectionObject *conn); HIDDEN int pq_tpc_command_locked(connectionObject *conn, - const char *cmd, XidObject *xid, + const char *cmd, const char *tid, PGresult **pgres, char **error, PyThreadState **tstate); HIDDEN int pq_is_busy(connectionObject *conn);