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* pre_file_scanner = file_list;
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock();
char* fullname = expand_dynamic_library_name(library_path);
for (file_scanner = file_list; file_scanner != NULL; file_scanner = file_scanner->next) {
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;
}
}
libraryLock.unLock();
}
/*

View File

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

View File

@ -28,6 +28,7 @@
#include "utils/hsearch.h"
#include "utils/memutils.h"
#include "utils/syscall_lock.h"
#include "postmaster/postmaster.h"
#include "storage/file/fio_device.h"
/* 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);
}
/*
* 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
* 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);
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.
*/
@ -367,6 +401,8 @@ void* internal_load_library(const char* libname)
u_sess->fmgr_cxt.file_init_tail = file_init_scanner;
}
libraryLock.unLock();
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.
*/
AutoMutexLock libraryLock(&dlerror_lock);
AutoMutexLock dlerrorLock(&dlerror_lock);
dlerrorLock.lock();
AutoMutexLock libraryLock(&file_list_lock);
libraryLock.lock();
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();
dlerrorLock.unLock();
#endif /* NOT_USED */
}

View File

@ -1799,7 +1799,7 @@ void PrintResourceOwnerLeakWarning()
ereport(WARNING, (errmsg("resource owner \"%s\" may leak", IsolatedResourceOwner->name)));
}
void ResourceOwnerReleasePthreadMutex()
void ResourceOwnerReleaseAllXactPthreadMutex()
{
ResourceOwner owner = t_thrd.utils_cxt.TopTransactionResourceOwner;
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)));
}
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)
{
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)));
}
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)
{
while (owner->nPthreadRWlock > 0) {

View File

@ -32,6 +32,8 @@ syscalllock env_lock;
syscalllock dlerror_lock;
syscalllock kerberos_conn_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

View File

@ -544,4 +544,5 @@ static void syscall_lock_init(void)
syscalllockInit(&dlerror_lock);
syscalllockInit(&kerberos_conn_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. */
// lock the same thread mutex can't be conflict in one thread.
ResourceOwnerReleasePthreadMutex();
ResourceOwnerReleaseAllXactPthreadMutex();
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. */
// 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);

View File

@ -157,8 +157,6 @@ void proc_exit_prepare(int code);
*/
void proc_exit(int code)
{
DynamicFileList* file_scanner = NULL;
if (ENABLE_DMS && t_thrd.proc_cxt.MyProcPid == PostmasterPid) {
// add cnt to avoid DmsCallbackThreadShmemInit to use UsedShmemSegAddr
(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);
}
}
if (t_thrd.utils_cxt.backend_reserved) {
ereport(DEBUG2, (errmodule(MOD_MEM),
errmsg("[BackendReservedExit] current thread role is: %d, used memory is: %d MB\n",
t_thrd.role, t_thrd.utils_cxt.trackedMemChunks)));
}
AtEOXact_SysDBCache(false);
audit_processlogout_unified();
(void)pgstat_report_waitstatus(STATE_WAIT_UNDEFINED);
@ -324,22 +325,8 @@ void proc_exit(int code)
if (t_thrd.postmaster_cxt.redirection_done)
ereport(LOG, (errmsg("Gaussdb exit(%d)", code)));
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) {
(void)pg_dlclose(file_scanner->handle);
}
#endif
pfree((char*)file_scanner);
file_scanner = NULL;
}
file_list = file_tail = NULL;
/* release all library at proc exit. */
internal_delete_library();
if (u_sess->attr.attr_resource.use_workload_manager)
gscgroup_free();

View File

@ -483,6 +483,7 @@ extern Datum GetTypeZeroValue(Form_pg_attribute att_tup);
extern Tuple ReplaceTupleNullCol(TupleDesc tupleDesc, TupleTableSlot* slot);
extern Datum ExecEvalArrayRef(ArrayRefExprState* astate, ExprContext* econtext, bool* isNull, ExprDoneCond* isDone);
extern int ResourceOwnerForgetIfExistPthreadMutex(ResourceOwner owner, pthread_mutex_t* pMutex, bool trace);
// AutoMutexLock
// Auto object for non-recursive pthread_mutex_t lock
@ -491,7 +492,11 @@ class AutoMutexLock {
public:
AutoMutexLock(pthread_mutex_t* mutex, bool trace = true)
: 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()
{
@ -538,10 +543,11 @@ public:
if (m_fLocked) {
int ret = 0;
if (t_thrd.utils_cxt.CurrentResourceOwner == NULL)
m_owner = NULL;
if (m_mutex == &file_list_lock) {
ret = ResourceOwnerForgetIfExistPthreadMutex(m_owner, m_mutex, m_trace);
} else {
ret = PthreadMutexUnlock(m_owner, m_mutex, m_trace);
}
m_fLocked = (ret == 0 ? false : true);
if (m_fLocked) {
/* 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 cancelShmemExit(pg_on_exit_callback function, Datum arg);
extern void internal_delete_library();
#endif /* IPC_H */

View File

@ -153,7 +153,7 @@ extern void ResourceOwnerEnlargePthreadMutex(ResourceOwner owner);
extern void PrintPthreadMutexLeakWarning(pthread_mutex_t* pMutex);
extern void PrintResourceOwnerLeakWarning();
extern void ResourceOwnerReleasePthreadMutex();
extern void ResourceOwnerReleaseAllXactPthreadMutex();
extern void ResourceOwnerEnlargePartitionMapRefs(ResourceOwner owner);
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 ResourceOwnerForgetGlobalIsExclusive(ResourceOwner owner, volatile uint32 *isexclusive);
extern void ResourceOwnerReleasePthreadMutex(ResourceOwner owner, bool isCommit);
extern void ResourceOwnerReleaseRWLock(ResourceOwner owner, bool isCommit);
extern void ResourceOwnerReleaseLocalCatCTup(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 kerberos_conn_lock;
extern syscalllock read_cipher_lock;
extern syscalllock file_list_lock;
#endif /* SYSCALL_LOCK_H_ */