/* * PortalCleanupHelper * * This could be called more than once. Each step should guard itself * so that it will be executed only once even if called more than once. * The *cleanupstate arg can be used to remember what has been done. */ static void PortalCleanupHelper(Portal portal, volatile int *cleanupstate) { QueryDesc *queryDesc = PortalGetQueryDesc(portal); /* * Shut down executor, if still running. We skip this during error abort, * since other mechanisms will take care of releasing executor resources, * and we can't be sure that ExecutorEnd itself wouldn't fail. */ portal->queryDesc = NULL; if (queryDesc) { if (queryDesc->estate) { /* * If we still have an estate -- then we need to cancel any * unfinished work. */ queryDesc->estate->cancelUnfinished = true; /* we do not need AfterTriggerEndQuery() here */ ExecutorEnd(queryDesc); } } /* * Terminate unneeded QE processes. */ if (*cleanupstate < 1 && Gp_role == GP_ROLE_DISPATCH) { *cleanupstate = 1; cleanupPortalGangs(portal); } /* * If resource scheduling is enabled, release the resource lock. */ if (portal->releaseResLock) { portal->releaseResLock = false; ResUnLockPortal(portal); } /** * Clean up backend's backoff entry */ if (gp_enable_resqueue_priority && Gp_role == GP_ROLE_DISPATCH && gp_session_id > -1) { BackoffBackendEntryExit(); } } /* PortalCleanupHelper */
/** * Invalidate the statement id corresponding to this backend so that it may * be eliminated from consideration by the sweeper early. */ static void BackoffStateAtExit(int code, Datum arg) { BackoffBackendEntryExit(); }