From 4b7b7ad334011d173d6401670841cbddcc13c903 Mon Sep 17 00:00:00 2001 From: LiHeng Date: Thu, 5 Aug 2021 22:50:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BA=BF=E7=A8=8B=E6=B1=A0fl?= =?UTF-8?q?ag=E9=95=BF=E8=B7=B3=E8=BD=AC=EF=BC=8C=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=85=B6=E4=BB=96session=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E9=94=81=EF=BC=8Chang?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gausskernel/process/stream/streamMain.cpp | 5 ++++- src/gausskernel/process/tcop/postgres.cpp | 5 ++++- .../process/threadpool/knl_thread.cpp | 2 ++ .../process/threadpool/threadpool_sessctl.cpp | 21 ++++++++++++++++--- src/gausskernel/storage/lmgr/proc.cpp | 4 +++- src/include/knl/knl_thread.h | 1 + src/include/threadpool/threadpool_sessctl.h | 4 ++-- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/gausskernel/process/stream/streamMain.cpp b/src/gausskernel/process/stream/streamMain.cpp index 3fb8decdf..3528cb98d 100644 --- a/src/gausskernel/process/stream/streamMain.cpp +++ b/src/gausskernel/process/stream/streamMain.cpp @@ -86,7 +86,10 @@ int StreamMain() int curTryCounter; int* oldTryCounter = NULL; if (sigsetjmp(local_sigjmp_buf, 1) != 0) { - t_thrd.int_cxt.ignoreBackendSignal = false; + t_thrd.int_cxt.ignoreBackendSignal = false; + if (g_threadPoolControler) { + g_threadPoolControler->GetSessionCtrl()->releaseLockIfNecessary(); + } /* reset STP thread local valueables */ stp_reset_opt_values(); diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index 555d8c1a8..913e2b081 100644 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -7328,7 +7328,10 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam int curTryCounter; int* oldTryCounter = NULL; if (sigsetjmp(local_sigjmp_buf, 1) != 0) { - t_thrd.int_cxt.ignoreBackendSignal = false; + t_thrd.int_cxt.ignoreBackendSignal = false; + if (g_threadPoolControler) { + g_threadPoolControler->GetSessionCtrl()->releaseLockIfNecessary(); + } gstrace_tryblock_exit(true, oldTryCounter); Assert(t_thrd.proc->dw_pos == -1); diff --git a/src/gausskernel/process/threadpool/knl_thread.cpp b/src/gausskernel/process/threadpool/knl_thread.cpp index d1308dd7a..5e49cedab 100644 --- a/src/gausskernel/process/threadpool/knl_thread.cpp +++ b/src/gausskernel/process/threadpool/knl_thread.cpp @@ -700,6 +700,8 @@ static void knl_t_sig_init(knl_t_sig_context* sig_cxt) { sig_cxt->signal_handle_cnt = 0; sig_cxt->gs_sigale_check_type = SIGNAL_CHECK_NONE; + sig_cxt->session_id = 0; + sig_cxt->cur_ctrl_index = 0; } static void knl_t_slot_init(knl_t_slot_context* slot_cxt) diff --git a/src/gausskernel/process/threadpool/threadpool_sessctl.cpp b/src/gausskernel/process/threadpool/threadpool_sessctl.cpp index 1e532a25b..908b91158 100644 --- a/src/gausskernel/process/threadpool/threadpool_sessctl.cpp +++ b/src/gausskernel/process/threadpool/threadpool_sessctl.cpp @@ -194,7 +194,7 @@ void ThreadPoolSessControl::MarkAllSessionClose() alock.unLock(); } -void ThreadPoolSessControl::CheckPermissionForSendSignal(knl_session_context* sess) +void ThreadPoolSessControl::CheckPermissionForSendSignal(knl_session_context* sess, sig_atomic_t* lock) { /* User id is invalid only when sometimes dealing with cancel signal. Because that permission is ensured by random cancel key, so we don't have to check the permission again. */ @@ -204,6 +204,7 @@ void ThreadPoolSessControl::CheckPermissionForSendSignal(knl_session_context* se /* Only superuser , DB owner and user himself have the permission to send singal. */ if (!superuser() && !pg_database_ownercheck(sess->proc_cxt.MyDatabaseId, u_sess->misc_cxt.CurrentUserId)) { if (sess->proc_cxt.MyRoleId != GetUserId()) { + *lock = 0; ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be system admin, db owner or have the same role to terminate other backend")))); @@ -211,6 +212,18 @@ void ThreadPoolSessControl::CheckPermissionForSendSignal(knl_session_context* se } } +void ThreadPoolSessControl::releaseLockIfNecessary() +{ + if (unlikely(t_thrd.sig_cxt.cur_ctrl_index != 0)) { + knl_sess_control* ctrl = &m_base[t_thrd.sig_cxt.cur_ctrl_index - m_maxReserveSessionCount]; + volatile sig_atomic_t plock = ctrl->lock; + if (plock != 0) { + plock = 0; + } + t_thrd.sig_cxt.cur_ctrl_index = 0; + } +} + int ThreadPoolSessControl::SendSignal(int ctrl_index, int signal) { Assert(signal != SIGHUP); @@ -221,6 +234,7 @@ int ThreadPoolSessControl::SendSignal(int ctrl_index, int signal) } knl_sess_control* ctrl = &m_base[ctrl_index - m_maxReserveSessionCount]; + t_thrd.sig_cxt.cur_ctrl_index = ctrl_index; volatile sig_atomic_t* plock = &ctrl->lock; sig_atomic_t val; do { @@ -232,13 +246,13 @@ int ThreadPoolSessControl::SendSignal(int ctrl_index, int signal) /* Session may be NULL when the session exits during the clean connection process. We do nothing if the session is NULL */ if (sess == NULL) { - /* restore the value */ + /* restore the value */ ctrl->lock = 0; status = ESRCH; break; } /* Check user permission, and we dont have user id for cancel request. */ - CheckPermissionForSendSignal(sess); + CheckPermissionForSendSignal(sess, (sig_atomic_t*)plock); if (sess->status == KNL_SESS_ATTACH) { t_thrd.sig_cxt.gs_sigale_check_type = SIGNAL_CHECK_SESS_KEY; t_thrd.sig_cxt.session_id = sess->session_id; @@ -265,6 +279,7 @@ int ThreadPoolSessControl::SendSignal(int ctrl_index, int signal) } pg_usleep(100); } while (true); + t_thrd.sig_cxt.cur_ctrl_index = 0; return status; } diff --git a/src/gausskernel/storage/lmgr/proc.cpp b/src/gausskernel/storage/lmgr/proc.cpp index 704a78106..2775edc62 100644 --- a/src/gausskernel/storage/lmgr/proc.cpp +++ b/src/gausskernel/storage/lmgr/proc.cpp @@ -1114,7 +1114,9 @@ static void ProcKill(int code, Datum arg) (errcode(ERRCODE_DATA_CORRUPTED), errmsg("there remain unreleased locks when process exists."))); } #endif - + if (g_threadPoolControler) { + g_threadPoolControler->GetSessionCtrl()->releaseLockIfNecessary(); + } /* * Release any LW locks I am holding. There really shouldn't be any, but * it's cheap to check again before we cut the knees off the LWLock diff --git a/src/include/knl/knl_thread.h b/src/include/knl/knl_thread.h index 1b37b4c4e..48ef97bad 100644 --- a/src/include/knl/knl_thread.h +++ b/src/include/knl/knl_thread.h @@ -1969,6 +1969,7 @@ typedef struct knl_t_sig_context { unsigned long signal_handle_cnt; GsSignalCheckType gs_sigale_check_type; uint64 session_id; + int cur_ctrl_index; } knl_t_sig_context; typedef struct knl_t_slot_context { diff --git a/src/include/threadpool/threadpool_sessctl.h b/src/include/threadpool/threadpool_sessctl.h index 91f9d91d2..0e8e13dc5 100644 --- a/src/include/threadpool/threadpool_sessctl.h +++ b/src/include/threadpool/threadpool_sessctl.h @@ -60,13 +60,13 @@ public: void SigHupHandler(); void HandlePoolerReload(); void CheckSessionTimeout(); - void CheckPermissionForSendSignal(knl_session_context* sess); + void CheckPermissionForSendSignal(knl_session_context* sess, sig_atomic_t* lock); void getSessionMemoryDetail(Tuplestorestate* tupStore, TupleDesc tupDesc, knl_sess_control** sess); knl_session_context* GetSessionByIdx(int idx); int FindCtrlIdxBySessId(uint64 id); TransactionId ListAllSessionGttFrozenxids(int maxSize, ThreadId *pids, TransactionId *xids, int *n); bool IsActiveListEmpty(); - + void releaseLockIfNecessary(); inline int GetActiveSessionCount() { return m_activeSessionCount;