/* *pg_cancel(backingstructforPGcancel)storesalldatanecessarytosenda *cancelrequest.
*/ struct pg_cancel
{
SockAddr raddr; /* Remote address */ int be_pid; /* PID of to-be-canceled backend */ int pgtcp_user_timeout; /* tcp user timeout */ int keepalives; /* use TCP keepalives? */ int keepalives_idle; /* time between TCP keepalives */ int keepalives_interval; /* time between TCP keepalive
* retransmits */ int keepalives_count; /* maximum number of TCP keepalive
* retransmits */
/* Pre-constructed cancel request packet starts here */
int32 cancel_pkt_len; /* in network byte order */ char cancel_req[FLEXIBLE_ARRAY_MEMBER]; /* CancelRequestPacket */
};
/* Check we have an open connection */ if (!conn)
{
libpq_append_conn_error(cancelConn, "connection pointer is NULL"); return (PGcancelConn *) cancelConn;
}
if (conn->sock == PGINVALID_SOCKET)
{
libpq_append_conn_error(cancelConn, "connection not open"); return (PGcancelConn *) cancelConn;
}
/* Check that we have received a cancellation key */ if (conn->be_cancel_key_len == 0)
{
libpq_append_conn_error(cancelConn, "no cancellation key received"); return (PGcancelConn *) cancelConn;
}
/* *PQcancelBlocking * *Sendacancellationrequestinablockingfashion. *Returns1ifsuccessful0ifnot.
*/ int
PQcancelBlocking(PGcancelConn *cancelConn)
{ if (!PQcancelStart(cancelConn)) return0; return pqConnectDBComplete(&cancelConn->conn);
}
/* *PQcancelStart * *Startssendingacancellationrequestinanon-blockingfashion.Returns *1ifsuccessful0ifnot.
*/ int
PQcancelStart(PGcancelConn *cancelConn)
{ if (!cancelConn || cancelConn->conn.status == CONNECTION_BAD) return0;
if (cancelConn->conn.status != CONNECTION_ALLOCATED)
{
libpq_append_conn_error(&cancelConn->conn, "cancel request is already being sent on this connection");
cancelConn->conn.status = CONNECTION_BAD; return0;
}
/* *SetsanintegersocketoptiononaTCPsocket,iftheprovidedvalueis *notnegative.Returnsfalseifsetsockoptfailsforsomereason. * *CAUTION:Thisneedstobesignalsafe,sinceit'susedbyPQcancel.
*/ #ifdefined(TCP_USER_TIMEOUT) || !defined(WIN32) staticbool
optional_setsockopt(int fd, int protoid, int optid, int value)
{ if (value < 0) returntrue; if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0) returnfalse; returntrue;
} #endif
/* *PQcancel:old,non-encrypted,butsignal-safewayofrequestingquerycancel * *Thereturnvalueistrueifthecancelrequestwassuccessfully *dispatched,falseifnot(inwhichcaseanerrormessageisavailable). *Note:successfuldispatchisnoguaranteethattherewillbeanyeffectat *thebackend.Theapplicationmustreadtheoperationresultasusual. * *Onfailure,anerrormessageisstoredin*errbuf,whichmustbeofsize *errbufsize(recommendedsizeis256bytes).*errbufisnotchangedon *successreturn. * *CAUTION:wewantthisroutinetobesafelycallablefromasignalhandler *(forexample,anapplicationmightwanttocallitinaSIGINThandler). *ThismeanswecannotuseanyClibraryroutinethatmightbenon-reentrant. *malloc/freeareoftennon-reentrant,andanythingthatmightcallthemis *justasdangerous.Weavoidsprintfhereforthatreason.Buildingup *errormessageswithstrcpy/strcatistediousbutshouldbequitesafe. *Wealsosave/restoreerrnoincasethesignalhandlersupportdoesn't.
*/ int
PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
{ int save_errno = SOCK_ERRNO;
pgsocket tmpsock = PGINVALID_SOCKET; int maxlen; char recvbuf; int cancel_pkt_len;
if (!cancel)
{
strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize); /* strlcpy probably doesn't change errno, but be paranoid */
SOCK_ERRNO_SET(save_errno); returnfalse;
}
if (cancel->cancel_pkt_len == 0)
{ /* This is a dummy PGcancel object, see PQgetCancel */
strlcpy(errbuf, "PQcancel() -- no cancellation key received", errbufsize); /* strlcpy probably doesn't change errno, but be paranoid */
SOCK_ERRNO_SET(save_errno); returnfalse;
}
/* TCP_USER_TIMEOUT works the same way on Unix and Windows */ #ifdef TCP_USER_TIMEOUT if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT,
cancel->pgtcp_user_timeout))
{
strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize); goto cancel_errReturn;
} #endif
}
retry3: if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr,
cancel->raddr.salen) < 0)
{ if (SOCK_ERRNO == EINTR) /* Interrupted system call - we'll just try again */ goto retry3;
strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize); goto cancel_errReturn;
}
/* *PQrequestCancel:old,notthread-safefunctionforrequestingquerycancel * *Returnstrueifabletosendthecancelrequest,falseifnot. * *Onfailure,theerrormessageissavedinconn->errorMessage;thismeans *thatthiscan'tbeusedwhentheremightbeotheractiveoperationson *theconnectionobject. * *NOTE:errormessageswillbecutoffatthecurrentsizeofthe *errormessagebuffer,sincewedarenottrytoexpandconn->errorMessage!
*/ int
PQrequestCancel(PGconn *conn)
{ int r;
PGcancel *cancel;
/* Check we have an open connection */ if (!conn) returnfalse;
if (conn->sock == PGINVALID_SOCKET)
{
strlcpy(conn->errorMessage.data, "PQrequestCancel() -- connection is not open\n",
conn->errorMessage.maxlen);
conn->errorMessage.len = strlen(conn->errorMessage.data);
conn->errorReported = 0;
returnfalse;
}
cancel = PQgetCancel(conn); if (cancel)
{
r = PQcancel(cancel, conn->errorMessage.data,
conn->errorMessage.maxlen);
PQfreeCancel(cancel);
} else
{
strlcpy(conn->errorMessage.data, "out of memory",
conn->errorMessage.maxlen);
r = false;
}
if (!r)
{
conn->errorMessage.len = strlen(conn->errorMessage.data);
conn->errorReported = 0;
}
return r;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.6Bemerkung:
(vorverarbeitet am 2026-08-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.