Add lock for loading so.

This commit is contained in:
totaj
2023-02-15 19:34:53 +08:00
parent 52dd7bc750
commit 3dac2a636a
12 changed files with 102 additions and 29 deletions

View File

@ -2301,6 +2301,10 @@ void delete_file_handle(const char* library_path)
DynamicFileList* file_scanner = NULL; DynamicFileList* file_scanner = NULL;
DynamicFileList* pre_file_scanner = file_list; DynamicFileList* pre_file_scanner = file_list;
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock();
char* fullname = expand_dynamic_library_name(library_path); char* fullname = expand_dynamic_library_name(library_path);
for (file_scanner = file_list; file_scanner != NULL; file_scanner = file_scanner->next) { for (file_scanner = file_list; file_scanner != NULL; file_scanner = file_scanner->next) {
if (strncmp(fullname, file_scanner->filename, strlen(fullname) + 1) == 0) { if (strncmp(fullname, file_scanner->filename, strlen(fullname) + 1) == 0) {
@ -2323,6 +2327,8 @@ void delete_file_handle(const char* library_path)
pre_file_scanner = file_scanner; pre_file_scanner = file_scanner;
} }
} }
libraryLock.unLock();
} }
/* /*

View File

@ -1064,6 +1064,7 @@ LocalSysDBCache::LocalSysDBCache()
void AtEOXact_SysDBCache(bool is_commit) void AtEOXact_SysDBCache(bool is_commit)
{ {
ResourceOwnerReleasePthreadMutex(t_thrd.lsc_cxt.local_sysdb_resowner, is_commit);
if (!EnableLocalSysCache()) { if (!EnableLocalSysCache()) {
ResourceOwnerReleaseRelationRef(t_thrd.lsc_cxt.local_sysdb_resowner, is_commit); ResourceOwnerReleaseRelationRef(t_thrd.lsc_cxt.local_sysdb_resowner, is_commit);
return; return;

View File

@ -28,6 +28,7 @@
#include "utils/hsearch.h" #include "utils/hsearch.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/syscall_lock.h" #include "utils/syscall_lock.h"
#include "postmaster/postmaster.h"
#include "storage/file/fio_device.h" #include "storage/file/fio_device.h"
/* Max size of error message of dlopen */ /* Max size of error message of dlopen */
@ -167,6 +168,36 @@ PGFunction lookup_external_function(void* filehandle, const char* funcname)
return (PGFunction)pg_dlsym(filehandle, funcname); return (PGFunction)pg_dlsym(filehandle, funcname);
} }
/*
* release all library at proc exit.
*/
void internal_delete_library()
{
DynamicFileList* file_scanner = NULL;
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock();
while (file_list != NULL) {
file_scanner = file_list;
file_list = file_list->next;
#ifndef ENABLE_MEMORY_CHECK
/*
* in the senario of ImmediateShutdown, it is not safe to close plugin
* as PM thread will not wait for all children threads exist(will send SIGQUIT signal) referring to pmdie
*/
if (g_instance.status != ImmediateShutdown && file_scanner->handle != NULL) {
(void)pg_dlclose(file_scanner->handle);
file_scanner->handle = NULL;
}
#endif
pfree((char*)file_scanner);
file_scanner = NULL;
}
file_list = file_tail = NULL;
libraryLock.unLock();
}
/* /*
* Load the specified dynamic-link library file, unless it already is * Load the specified dynamic-link library file, unless it already is
* loaded. Return the pg_dl* handle for the file. * loaded. Return the pg_dl* handle for the file.
@ -186,6 +217,9 @@ void* internal_load_library(const char* libname)
char* file = last_dir_separator(libname); char* file = last_dir_separator(libname);
file = (file == NULL) ? ((char*)libname) : (file + 1); file = (file == NULL) ? ((char*)libname) : (file + 1);
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock();
/* /*
* Scan the list of loaded FILES to see if the file has been loaded. * Scan the list of loaded FILES to see if the file has been loaded.
*/ */
@ -367,6 +401,8 @@ void* internal_load_library(const char* libname)
u_sess->fmgr_cxt.file_init_tail = file_init_scanner; u_sess->fmgr_cxt.file_init_tail = file_init_scanner;
} }
libraryLock.unLock();
return file_scanner->handle; return file_scanner->handle;
} }
@ -490,8 +526,9 @@ static void internal_unload_library(const char* libname)
* inode, else internal_load_library() will still think it's present. * inode, else internal_load_library() will still think it's present.
*/ */
AutoMutexLock libraryLock(&dlerror_lock); AutoMutexLock dlerrorLock(&dlerror_lock);
dlerrorLock.lock();
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock(); libraryLock.lock();
for (file_scanner = file_list; file_scanner != NULL; file_scanner = nxt) { for (file_scanner = file_list; file_scanner != NULL; file_scanner = nxt) {
@ -523,6 +560,7 @@ static void internal_unload_library(const char* libname)
} }
libraryLock.unLock(); libraryLock.unLock();
dlerrorLock.unLock();
#endif /* NOT_USED */ #endif /* NOT_USED */
} }

View File

@ -1799,7 +1799,7 @@ void PrintResourceOwnerLeakWarning()
ereport(WARNING, (errmsg("resource owner \"%s\" may leak", IsolatedResourceOwner->name))); ereport(WARNING, (errmsg("resource owner \"%s\" may leak", IsolatedResourceOwner->name)));
} }
void ResourceOwnerReleasePthreadMutex() void ResourceOwnerReleaseAllXactPthreadMutex()
{ {
ResourceOwner owner = t_thrd.utils_cxt.TopTransactionResourceOwner; ResourceOwner owner = t_thrd.utils_cxt.TopTransactionResourceOwner;
ResourceOwner child; ResourceOwner child;
@ -2012,6 +2012,23 @@ void ResourceOwnerForgetPthreadRWlock(ResourceOwner owner, pthread_rwlock_t* pRW
errmsg("pthread rwlock is not owned by resource owner %s", owner->name))); errmsg("pthread rwlock is not owned by resource owner %s", owner->name)));
} }
int ResourceOwnerForgetIfExistPthreadMutex(ResourceOwner owner, pthread_mutex_t* pMutex, bool trace)
{
pthread_mutex_t** mutexs = owner->pThdMutexs;
int ns1 = owner->nPthreadMutex - 1;
if (!owner->valid) {
return 0;
}
for (int i = ns1; i >= 0; i--) {
if (mutexs[i] == pMutex) {
return PthreadMutexUnlock(owner, pMutex, trace);
}
}
return 0;
}
void ResourceOwnerEnlargeLocalCatCList(ResourceOwner owner) void ResourceOwnerEnlargeLocalCatCList(ResourceOwner owner)
{ {
int newmax; int newmax;
@ -2224,6 +2241,17 @@ void ResourceOwnerForgetGlobalBaseEntry(ResourceOwner owner, GlobalBaseEntry* en
errmsg("the global base entry is not owned by resource owner %s", owner->name))); errmsg("the global base entry is not owned by resource owner %s", owner->name)));
} }
void ResourceOwnerReleasePthreadMutex(ResourceOwner owner, bool isCommit)
{
while (owner->nPthreadMutex > 0) {
if (isCommit) {
PrintGlobalSysCacheLeakWarning(owner, "MutexLock");
}
/* unlock do -- */
PthreadMutexUnlock(owner, owner->pThdMutexs[owner->nPthreadMutex - 1]);
}
}
void ResourceOwnerReleaseRWLock(ResourceOwner owner, bool isCommit) void ResourceOwnerReleaseRWLock(ResourceOwner owner, bool isCommit)
{ {
while (owner->nPthreadRWlock > 0) { while (owner->nPthreadRWlock > 0) {

View File

@ -32,6 +32,8 @@ syscalllock env_lock;
syscalllock dlerror_lock; syscalllock dlerror_lock;
syscalllock kerberos_conn_lock; syscalllock kerberos_conn_lock;
syscalllock read_cipher_lock; syscalllock read_cipher_lock;
syscalllock file_list_lock;
/* /*
* @Description: Atomic set val into *ptr in a 32-bit address, and return the previous pointed by ptr * @Description: Atomic set val into *ptr in a 32-bit address, and return the previous pointed by ptr

View File

@ -544,4 +544,5 @@ static void syscall_lock_init(void)
syscalllockInit(&dlerror_lock); syscalllockInit(&dlerror_lock);
syscalllockInit(&kerberos_conn_lock); syscalllockInit(&kerberos_conn_lock);
syscalllockInit(&read_cipher_lock); syscalllockInit(&read_cipher_lock);
syscalllockInit(&file_list_lock);
} }

View File

@ -904,7 +904,7 @@ void StreamNodeGroup::destroy(StreamObjStatus status)
/* We must relase all pthread mutex by my thread, Or it will dead lock. But it is not a good solution. */ /* We must relase all pthread mutex by my thread, Or it will dead lock. But it is not a good solution. */
// lock the same thread mutex can't be conflict in one thread. // lock the same thread mutex can't be conflict in one thread.
ResourceOwnerReleasePthreadMutex(); ResourceOwnerReleaseAllXactPthreadMutex();
WaitState oldStatus = pgstat_report_waitstatus(STATE_STREAM_WAIT_NODEGROUP_DESTROY); WaitState oldStatus = pgstat_report_waitstatus(STATE_STREAM_WAIT_NODEGROUP_DESTROY);
@ -954,7 +954,7 @@ void StreamNodeGroup::syncQuit(StreamObjStatus status)
/* We must relase all pthread mutex by my thread, Or it will dead lock. But it is not a good solution. */ /* We must relase all pthread mutex by my thread, Or it will dead lock. But it is not a good solution. */
// lock the same thread mutex can't be conflict in one thread. // lock the same thread mutex can't be conflict in one thread.
ResourceOwnerReleasePthreadMutex(); ResourceOwnerReleaseAllXactPthreadMutex();
WaitState oldStatus = pgstat_report_waitstatus(STATE_STREAM_WAIT_THREAD_SYNC_QUIT); WaitState oldStatus = pgstat_report_waitstatus(STATE_STREAM_WAIT_THREAD_SYNC_QUIT);

View File

@ -157,8 +157,6 @@ void proc_exit_prepare(int code);
*/ */
void proc_exit(int code) void proc_exit(int code)
{ {
DynamicFileList* file_scanner = NULL;
if (ENABLE_DMS && t_thrd.proc_cxt.MyProcPid == PostmasterPid) { if (ENABLE_DMS && t_thrd.proc_cxt.MyProcPid == PostmasterPid) {
// add cnt to avoid DmsCallbackThreadShmemInit to use UsedShmemSegAddr // add cnt to avoid DmsCallbackThreadShmemInit to use UsedShmemSegAddr
(void)pg_atomic_add_fetch_u32(&g_instance.dms_cxt.inProcExitCnt, 1); (void)pg_atomic_add_fetch_u32(&g_instance.dms_cxt.inProcExitCnt, 1);
@ -167,12 +165,15 @@ void proc_exit(int code)
pg_usleep(WAIT_DMS_INIT_TIMEOUT); pg_usleep(WAIT_DMS_INIT_TIMEOUT);
} }
} }
if (t_thrd.utils_cxt.backend_reserved) { if (t_thrd.utils_cxt.backend_reserved) {
ereport(DEBUG2, (errmodule(MOD_MEM), ereport(DEBUG2, (errmodule(MOD_MEM),
errmsg("[BackendReservedExit] current thread role is: %d, used memory is: %d MB\n", errmsg("[BackendReservedExit] current thread role is: %d, used memory is: %d MB\n",
t_thrd.role, t_thrd.utils_cxt.trackedMemChunks))); t_thrd.role, t_thrd.utils_cxt.trackedMemChunks)));
} }
AtEOXact_SysDBCache(false);
audit_processlogout_unified(); audit_processlogout_unified();
(void)pgstat_report_waitstatus(STATE_WAIT_UNDEFINED); (void)pgstat_report_waitstatus(STATE_WAIT_UNDEFINED);
@ -324,22 +325,8 @@ void proc_exit(int code)
if (t_thrd.postmaster_cxt.redirection_done) if (t_thrd.postmaster_cxt.redirection_done)
ereport(LOG, (errmsg("Gaussdb exit(%d)", code))); ereport(LOG, (errmsg("Gaussdb exit(%d)", code)));
while (file_list != NULL) { /* release all library at proc exit. */
file_scanner = file_list; internal_delete_library();
file_list = file_list->next;
#ifndef ENABLE_MEMORY_CHECK
/*
* in the senario of ImmediateShutdown, it is not safe to close plugin
* as PM thread will not wait for all children threads exist(will send SIGQUIT signal) referring to pmdie
*/
if (g_instance.status != ImmediateShutdown) {
(void)pg_dlclose(file_scanner->handle);
}
#endif
pfree((char*)file_scanner);
file_scanner = NULL;
}
file_list = file_tail = NULL;
if (u_sess->attr.attr_resource.use_workload_manager) if (u_sess->attr.attr_resource.use_workload_manager)
gscgroup_free(); gscgroup_free();

View File

@ -483,6 +483,7 @@ extern Datum GetTypeZeroValue(Form_pg_attribute att_tup);
extern Tuple ReplaceTupleNullCol(TupleDesc tupleDesc, TupleTableSlot* slot); extern Tuple ReplaceTupleNullCol(TupleDesc tupleDesc, TupleTableSlot* slot);
extern Datum ExecEvalArrayRef(ArrayRefExprState* astate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone); extern Datum ExecEvalArrayRef(ArrayRefExprState* astate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
extern int ResourceOwnerForgetIfExistPthreadMutex(ResourceOwner owner, pthread_mutex_t* pMutex, bool trace);
// AutoMutexLock // AutoMutexLock
// Auto object for non-recursive pthread_mutex_t lock // Auto object for non-recursive pthread_mutex_t lock
@ -491,7 +492,11 @@ class AutoMutexLock {
public: public:
AutoMutexLock(pthread_mutex_t* mutex, bool trace = true) AutoMutexLock(pthread_mutex_t* mutex, bool trace = true)
: m_mutex(mutex), m_fLocked(false), m_trace(trace), m_owner(t_thrd.utils_cxt.CurrentResourceOwner) : m_mutex(mutex), m_fLocked(false), m_trace(trace), m_owner(t_thrd.utils_cxt.CurrentResourceOwner)
{} {
if (mutex == &file_list_lock) {
m_owner = t_thrd.lsc_cxt.local_sysdb_resowner;
}
}
~AutoMutexLock() ~AutoMutexLock()
{ {
@ -538,10 +543,11 @@ public:
if (m_fLocked) { if (m_fLocked) {
int ret = 0; int ret = 0;
if (t_thrd.utils_cxt.CurrentResourceOwner == NULL) if (m_mutex == &file_list_lock) {
m_owner = NULL; ret = ResourceOwnerForgetIfExistPthreadMutex(m_owner, m_mutex, m_trace);
} else {
ret = PthreadMutexUnlock(m_owner, m_mutex, m_trace); ret = PthreadMutexUnlock(m_owner, m_mutex, m_trace);
}
m_fLocked = (ret == 0 ? false : true); m_fLocked = (ret == 0 ? false : true);
if (m_fLocked) { if (m_fLocked) {
/* this should never happen, system may be completely in a mess */ /* this should never happen, system may be completely in a mess */

View File

@ -85,4 +85,6 @@ extern pthread_mutex_t gLocaleMutex;
extern void CreateSharedMemoryAndSemaphores(bool makePrivate, int port); extern void CreateSharedMemoryAndSemaphores(bool makePrivate, int port);
extern void cancelShmemExit(pg_on_exit_callback function, Datum arg); extern void cancelShmemExit(pg_on_exit_callback function, Datum arg);
extern void internal_delete_library();
#endif /* IPC_H */ #endif /* IPC_H */

View File

@ -153,7 +153,7 @@ extern void ResourceOwnerEnlargePthreadMutex(ResourceOwner owner);
extern void PrintPthreadMutexLeakWarning(pthread_mutex_t* pMutex); extern void PrintPthreadMutexLeakWarning(pthread_mutex_t* pMutex);
extern void PrintResourceOwnerLeakWarning(); extern void PrintResourceOwnerLeakWarning();
extern void ResourceOwnerReleasePthreadMutex(); extern void ResourceOwnerReleaseAllXactPthreadMutex();
extern void ResourceOwnerEnlargePartitionMapRefs(ResourceOwner owner); extern void ResourceOwnerEnlargePartitionMapRefs(ResourceOwner owner);
extern void ResourceOwnerRememberPartitionMapRef(ResourceOwner owner, PartitionMap* partmap); extern void ResourceOwnerRememberPartitionMapRef(ResourceOwner owner, PartitionMap* partmap);
@ -197,6 +197,7 @@ extern void ResourceOwnerEnlargeGlobalIsExclusive(ResourceOwner owner);
extern void ResourceOwnerRememberGlobalIsExclusive(ResourceOwner owner, volatile uint32 *isexclusive); extern void ResourceOwnerRememberGlobalIsExclusive(ResourceOwner owner, volatile uint32 *isexclusive);
extern void ResourceOwnerForgetGlobalIsExclusive(ResourceOwner owner, volatile uint32 *isexclusive); extern void ResourceOwnerForgetGlobalIsExclusive(ResourceOwner owner, volatile uint32 *isexclusive);
extern void ResourceOwnerReleasePthreadMutex(ResourceOwner owner, bool isCommit);
extern void ResourceOwnerReleaseRWLock(ResourceOwner owner, bool isCommit); extern void ResourceOwnerReleaseRWLock(ResourceOwner owner, bool isCommit);
extern void ResourceOwnerReleaseLocalCatCTup(ResourceOwner owner, bool isCommit); extern void ResourceOwnerReleaseLocalCatCTup(ResourceOwner owner, bool isCommit);
extern void ResourceOwnerReleaseLocalCatCList(ResourceOwner owner, bool isCommit); extern void ResourceOwnerReleaseLocalCatCList(ResourceOwner owner, bool isCommit);

View File

@ -56,5 +56,6 @@ extern syscalllock env_lock;
extern syscalllock dlerror_lock; extern syscalllock dlerror_lock;
extern syscalllock kerberos_conn_lock; extern syscalllock kerberos_conn_lock;
extern syscalllock read_cipher_lock; extern syscalllock read_cipher_lock;
extern syscalllock file_list_lock;
#endif /* SYSCALL_LOCK_H_ */ #endif /* SYSCALL_LOCK_H_ */