Thread: How to check for pending CancelRequest from C/C++ function
Hi all, I writing some functions for postgresql extension in C/C++ and I would like to be able to check for a pending CancelRequest from the frontend so I can take appropriate action to honor this request. 1. How to I check if a request is pending? 2. What is the appropriate action? I assume this should be something like: a. cleanup as needed b. elog(ERROR, "terminated at user cancel request."); Is there an example of this in contrib or elsewhere that you can point me to? Thanks, -Steve
Stephen Woodbridge <woodbri@swoodbridge.com> writes: > I writing some functions for postgresql extension in C/C++ and I would > like to be able to check for a pending CancelRequest from the frontend > so I can take appropriate action to honor this request. Put "CHECK_FOR_INTERRUPTS();" in some suitably safe place. regards, tom lane
On 1/6/2014 10:32 AM, Tom Lane wrote: > Stephen Woodbridge <woodbri@swoodbridge.com> writes: >> I writing some functions for postgresql extension in C/C++ and I would >> like to be able to check for a pending CancelRequest from the frontend >> so I can take appropriate action to honor this request. > > Put "CHECK_FOR_INTERRUPTS();" in some suitably safe place. Thanks! Looking at this macro its doing if (InterruptPending) ProcessInterrupts(); Am I correct in assuming that ProcessInterrupts() may not return? So if I need to clean up then I should check do something like: if (InterruptPending) { /* cleanup here */ ProcessInterrupts(); } Similarly if I'm in C++ code I can probably include miscadmin.h as an extern C to get access to this. Thanks again, -Steve
Stephen Woodbridge <woodbri@swoodbridge.com> writes: > On 1/6/2014 10:32 AM, Tom Lane wrote: >> Put "CHECK_FOR_INTERRUPTS();" in some suitably safe place. > So if I need to clean up then I should check do something like: > if (InterruptPending) { > /* cleanup here */ > ProcessInterrupts(); > } Uh, no, you should just do "CHECK_FOR_INTERRUPTS();", because that's all that's going to happen if any subroutine you happen to call chooses to check for query cancel. Or more generally, any sort of error is going to take control away from you. If you have cleanup that has to happen, you need to arrange for that to happen during transaction or subtransaction abort. In most cases there is infrastructure that can help you with this, but if you're dealing with some resource not known to PG core code then you might have to resort to a transaction-end callback function or something like that. Depending on how localized the cleanup requirement is, you might be able to use a PG_TRY/PG_CATCH block to enforce cleanup when an error is thrown. > Similarly if I'm in C++ code I can probably include miscadmin.h as an > extern C to get access to this. One of the main problems with using C++ for PG extensions is that its exception infrastructure doesn't play nice with the longjmps underlying PG error processing. You can create interface code to translate between the two conventions, but it's notationally tedious. regards, tom lane