* PQcancel and PQrequestCancel: attempt to request cancellation of the * current operation. * * 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. * * CAUT
| 4565 | * between the two versions of the cancel function possible. |
| 4566 | */ |
| 4567 | static int |
| 4568 | internal_cancel(SockAddr *raddr, int be_pid, int be_key, |
| 4569 | char *errbuf, int errbufsize, bool requestFinish) |
| 4570 | { |
| 4571 | int save_errno = SOCK_ERRNO; |
| 4572 | pgsocket tmpsock = PGINVALID_SOCKET; |
| 4573 | int maxlen; |
| 4574 | struct |
| 4575 | { |
| 4576 | uint32 packetlen; |
| 4577 | CancelRequestPacket cp; |
| 4578 | } crp; |
| 4579 | |
| 4580 | #ifndef WIN32 |
| 4581 | struct pollfd pollFds[1]; |
| 4582 | int pollRet; |
| 4583 | |
| 4584 | retry2: |
| 4585 | #endif |
| 4586 | /* |
| 4587 | * We need to open a temporary connection to the postmaster. Do this with |
| 4588 | * only kernel calls. |
| 4589 | */ |
| 4590 | if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET) |
| 4591 | { |
| 4592 | strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize); |
| 4593 | goto cancel_errReturn; |
| 4594 | } |
| 4595 | retry3: |
| 4596 | if (connect(tmpsock, (struct sockaddr *) &raddr->addr, |
| 4597 | raddr->salen) < 0) |
| 4598 | { |
| 4599 | if (SOCK_ERRNO == EINTR) |
| 4600 | /* Interrupted system call - we'll just try again */ |
| 4601 | goto retry3; |
| 4602 | strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize); |
| 4603 | goto cancel_errReturn; |
| 4604 | } |
| 4605 | |
| 4606 | /* |
| 4607 | * We needn't set nonblocking I/O or NODELAY options here. |
| 4608 | */ |
| 4609 | |
| 4610 | /* Create and send the cancel request packet. */ |
| 4611 | |
| 4612 | crp.packetlen = pg_hton32((uint32) sizeof(crp)); |
| 4613 | if (requestFinish) |
| 4614 | crp.cp.cancelRequestCode = (MsgType) pg_hton32(FINISH_REQUEST_CODE); |
| 4615 | else |
| 4616 | crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE); |
| 4617 | crp.cp.backendPID = pg_hton32(be_pid); |
| 4618 | crp.cp.cancelAuthCode = pg_hton32(be_key); |
| 4619 | |
| 4620 | retry4: |
| 4621 | if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp)) |
| 4622 | { |
| 4623 | if (SOCK_ERRNO == EINTR) |
| 4624 | /* Interrupted system call - we'll just try again */ |
no test coverage detected