/* * Copyright (c) 2020 Huawei Technologies Co.,Ltd. * * openGauss is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. * --------------------------------------------------------------------------------------- * * threadpool_worker.h * ThreadPoolWorker will get an active session from ThreadPoolListener, * read command from the session and execute the command. This class is * also response to init and free session. * * IDENTIFICATION * src/include/threadpool/threadpool_worker.h * * --------------------------------------------------------------------------------------- */ #ifndef THREAD_POOL_WORKER_H #define THREAD_POOL_WORKER_H #include "lib/dllist.h" #include "knl/knl_variable.h" #define THRD_SIGTERM 0x00000001 #define THRD_EXIT 0x00000010 extern void SetThreadLocalGUC(knl_session_context* session); /* * List of active backends (or child processes anyway; we don't actually * know whether a given child has become a backend or is still in the * authorization phase). This is used mainly to keep track of how many * children we have and send them appropriate signals when necessary. * * "Special" children such as the startup, bgwriter and autovacuum launcher * tasks are not in this list Autovacuum worker and walsender processes are * in it. Also, "dead_end" children are in it: these are children launched just * for the purpose of sending a friendly rejection message to a would-be * client. We must track them because they are attached to shared memory, * but we know they will never become live backends. dead_end children are * not assigned a PMChildSlot. */ typedef struct Backend { ThreadId pid; /* process id of backend */ knl_thread_role role; /* thread role */ long cancel_key; /* cancel key for cancels for this backend */ int child_slot; /* PMChildSlot for this backend, if any */ bool is_autovacuum; /* is it an autovacuum process? */ volatile bool dead_end; /* is it going to send an quit? */ volatile int flag; Dlelem elem; /* list link in BackendList */ } Backend; typedef enum { THREAD_UNINIT = 0, THREAD_RUN, THREAD_PENDING, THREAD_EXIT, // set by PM , as PM down. } ThreadStatus; typedef enum { TWORKER_HOLDSESSIONLOCK = 0, TWORKER_TWOPHASECOMMIT, TWORKER_HOLDLWLOCK, TWORKER_GETNEXTXID, TWORKER_STILLINTRANS, TWORKER_UNCONSUMEMESSAGE, TWORKER_CANSEEKNEXTSESSION, TWORKER_PREDEADSESSION } ThreadStayReason; class ThreadPoolGroup; class ThreadPoolWorker : public BaseObject { public: ThreadPoolWorker(uint idx, ThreadPoolGroup* group, pthread_mutex_t* mutex, pthread_cond_t* m_cond); ~ThreadPoolWorker(); int StartUp(); void ShutDown(); void NotifyReady(); void WaitMission(); void CleanUpSession(bool threadexit); void CleanUpSessionWithLock(); bool WakeUpToWork(knl_session_context* session); void WakeUpToUpdate(ThreadStatus status); bool WakeUpToPendingIfFree(); friend class ThreadPoolListener; inline ThreadPoolGroup* GetGroup() { return m_group; } inline ThreadId GetThreadId() { return m_tid; } inline void SetSession(knl_session_context* session) { m_currentSession = session; } const inline knl_thrd_context *GetThreadContextPtr() { return m_thrd; } inline ThreadStatus GetthreadStatus() { pg_memory_barrier(); return m_threadStatus; } static Backend* CreateBackend(); static void AddBackend(Backend* bn); public: volatile int m_waitState; private: void CleanThread(); bool AttachSessionToThread(); void DetachSessionFromThread(); void WaitNextSession(); bool InitPort(Port* port); void FreePort(Port* port); void Pending(); void ShutDownIfNecessary(); void RestoreSessionVariable(); void RestoreThreadVariable(); void RestoreLocaleInfo(); void SetSessionInfo(); private: ThreadId m_tid; uint m_idx; knl_session_context* m_currentSession; volatile ThreadStatus m_threadStatus; bool m_thrd_idle_waiting; ThreadStayReason m_reason; Dlelem m_elem; ThreadPoolGroup* m_group; pthread_mutex_t* m_mutex; pthread_cond_t* m_cond; knl_thrd_context *m_thrd; }; extern void init_session_share_memory(); #endif /* THREAD_POOL_WORKER_H */