0001-Refactor-to-remove-internal_cancel-helper.patch
application/octet-stream
Filename: 0001-Refactor-to-remove-internal_cancel-helper.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Refactor to remove internal_cancel helper
| File | + | − |
|---|---|---|
| src/interfaces/libpq/fe-connect.c | 22 | 36 |
From c7eee6f7c3f5426964c07c6bd9a44247c2017d4e Mon Sep 17 00:00:00 2001
From: Jelte Fennema <jelte.fennema@microsoft.com>
Date: Thu, 6 Jan 2022 15:11:22 +0100
Subject: [PATCH 1/3] Refactor to remove internal_cancel helper
To simplify future changes to PQcancel this removes the internal_cancel
helper function. Now PQrequestCancel calls PQcancel internally, instead
of having both PQcancel and PQrequestCancel call the shared
internal_cancel helper function.
---
src/interfaces/libpq/fe-connect.c | 58 ++++++++++++-------------------
1 file changed, 22 insertions(+), 36 deletions(-)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 9b6a6939f0..85fce856a5 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -4406,14 +4406,17 @@ PQfreeCancel(PGcancel *cancel)
/*
- * PQcancel and PQrequestCancel: attempt to request cancellation of the
- * current operation.
+ * PQcancel: request query cancel
*
* The return value is true if the cancel request was successfully
* dispatched, false if not (in which case an error message is available).
* Note: successful dispatch is no guarantee that there will be any effect at
* the backend. The application must read the operation result as usual.
*
+ * On failure, an error message is stored in *errbuf, which must be of size
+ * errbufsize (recommended size is 256 bytes). *errbuf is not changed on
+ * success return.
+ *
* CAUTION: we want this routine to be safely callable from a signal handler
* (for example, an application might want to call it in a SIGINT handler).
* This means we cannot use any C library routine that might be non-reentrant.
@@ -4421,13 +4424,9 @@ PQfreeCancel(PGcancel *cancel)
* just as dangerous. We avoid sprintf here for that reason. Building up
* error messages with strcpy/strcat is tedious but should be quite safe.
* We also save/restore errno in case the signal handler support doesn't.
- *
- * internal_cancel() is an internal helper function to make code-sharing
- * between the two versions of the cancel function possible.
*/
-static int
-internal_cancel(SockAddr *raddr, int be_pid, int be_key,
- char *errbuf, int errbufsize)
+int
+PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
{
int save_errno = SOCK_ERRNO;
pgsocket tmpsock = PGINVALID_SOCKET;
@@ -4439,18 +4438,24 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
CancelRequestPacket cp;
} crp;
+ if (!cancel)
+ {
+ strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
+ return false;
+ }
+
/*
* We need to open a temporary connection to the postmaster. Do this with
* only kernel calls.
*/
- if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
+ if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
{
strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
goto cancel_errReturn;
}
retry3:
- if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
- raddr->salen) < 0)
+ if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
+ cancel->raddr.salen) < 0)
{
if (SOCK_ERRNO == EINTR)
/* Interrupted system call - we'll just try again */
@@ -4467,8 +4472,8 @@ retry3:
crp.packetlen = pg_hton32((uint32) sizeof(crp));
crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
- crp.cp.backendPID = pg_hton32(be_pid);
- crp.cp.cancelAuthCode = pg_hton32(be_key);
+ crp.cp.backendPID = pg_hton32(cancel->be_pid);
+ crp.cp.cancelAuthCode = pg_hton32(cancel->be_key);
retry4:
if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
@@ -4520,27 +4525,6 @@ cancel_errReturn:
return false;
}
-/*
- * PQcancel: request query cancel
- *
- * Returns true if able to send the cancel request, false if not.
- *
- * On failure, an error message is stored in *errbuf, which must be of size
- * errbufsize (recommended size is 256 bytes). *errbuf is not changed on
- * success return.
- */
-int
-PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
-{
- if (!cancel)
- {
- strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
- return false;
- }
-
- return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
- errbuf, errbufsize);
-}
/*
* PQrequestCancel: old, not thread-safe function for requesting query cancel
@@ -4558,6 +4542,7 @@ int
PQrequestCancel(PGconn *conn)
{
int r;
+ PGcancel *cancel;
/* Check we have an open connection */
if (!conn)
@@ -4573,8 +4558,9 @@ PQrequestCancel(PGconn *conn)
return false;
}
- r = internal_cancel(&conn->raddr, conn->be_pid, conn->be_key,
- conn->errorMessage.data, conn->errorMessage.maxlen);
+ cancel = PQgetCancel(conn);
+ r = PQcancel(cancel, conn->errorMessage.data, conn->errorMessage.maxlen);
+ PQfreeCancel(cancel);
if (!r)
conn->errorMessage.len = strlen(conn->errorMessage.data);
--
2.17.1