@ -133,7 +133,7 @@ static void pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue);
static void pgfdw_reject_incomplete_xact_state_change ( ConnCacheEntry * entry ) ;
static void pgfdw_reject_incomplete_xact_state_change ( ConnCacheEntry * entry ) ;
static void pgfdw_reset_xact_state ( ConnCacheEntry * entry , bool toplevel ) ;
static void pgfdw_reset_xact_state ( ConnCacheEntry * entry , bool toplevel ) ;
static bool pgfdw_cancel_query ( PGconn * conn ) ;
static bool pgfdw_cancel_query ( PGconn * conn ) ;
static bool pgfdw_cancel_query_begin ( PGconn * conn ) ;
static bool pgfdw_cancel_query_begin ( PGconn * conn , TimestampTz endtime ) ;
static bool pgfdw_cancel_query_end ( PGconn * conn , TimestampTz endtime ,
static bool pgfdw_cancel_query_end ( PGconn * conn , TimestampTz endtime ,
bool consume_input ) ;
bool consume_input ) ;
static bool pgfdw_exec_cleanup_query ( PGconn * conn , const char * query ,
static bool pgfdw_exec_cleanup_query ( PGconn * conn , const char * query ,
@ -1315,36 +1315,31 @@ pgfdw_cancel_query(PGconn *conn)
endtime = TimestampTzPlusMilliseconds ( GetCurrentTimestamp ( ) ,
endtime = TimestampTzPlusMilliseconds ( GetCurrentTimestamp ( ) ,
CONNECTION_CLEANUP_TIMEOUT ) ;
CONNECTION_CLEANUP_TIMEOUT ) ;
if ( ! pgfdw_cancel_query_begin ( conn ) )
if ( ! pgfdw_cancel_query_begin ( conn , endtime ) )
return false ;
return false ;
return pgfdw_cancel_query_end ( conn , endtime , false ) ;
return pgfdw_cancel_query_end ( conn , endtime , false ) ;
}
}
/*
* Submit a cancel request to the given connection , waiting only until
* the given time .
*
* We sleep interruptibly until we receive confirmation that the cancel
* request has been accepted , and if it is , return true ; if the timeout
* lapses without that , or the request fails for whatever reason , return
* false .
*/
static bool
static bool
pgfdw_cancel_query_begin ( PGconn * conn )
pgfdw_cancel_query_begin ( PGconn * conn , TimestampTz endtime )
{
{
PGcancel * cancel ;
char * errormsg = libpqsrv_cancel ( conn , endtime ) ;
char errbuf [ 256 ] ;
/*
if ( errormsg ! = NULL )
* Issue cancel request . Unfortunately , there ' s no good way to limit the
ereport ( WARNING ,
* amount of time that we might block inside PQgetCancel ( ) .
errcode ( ERRCODE_CONNECTION_FAILURE ) ,
*/
errmsg ( " could not send cancel request: %s " , errormsg ) ) ;
if ( ( cancel = PQgetCancel ( conn ) ) )
{
if ( ! PQcancel ( cancel , errbuf , sizeof ( errbuf ) ) )
{
ereport ( WARNING ,
( errcode ( ERRCODE_CONNECTION_FAILURE ) ,
errmsg ( " could not send cancel request: %s " ,
errbuf ) ) ) ;
PQfreeCancel ( cancel ) ;
return false ;
}
PQfreeCancel ( cancel ) ;
}
return true ;
return errormsg = = NULL ;
}
}
static bool
static bool
@ -1685,7 +1680,11 @@ pgfdw_abort_cleanup_begin(ConnCacheEntry *entry, bool toplevel,
*/
*/
if ( PQtransactionStatus ( entry - > conn ) = = PQTRANS_ACTIVE )
if ( PQtransactionStatus ( entry - > conn ) = = PQTRANS_ACTIVE )
{
{
if ( ! pgfdw_cancel_query_begin ( entry - > conn ) )
TimestampTz endtime ;
endtime = TimestampTzPlusMilliseconds ( GetCurrentTimestamp ( ) ,
CONNECTION_CLEANUP_TIMEOUT ) ;
if ( ! pgfdw_cancel_query_begin ( entry - > conn , endtime ) )
return false ; /* Unable to cancel running query */
return false ; /* Unable to cancel running query */
* cancel_requested = lappend ( * cancel_requested , entry ) ;
* cancel_requested = lappend ( * cancel_requested , entry ) ;
}
}