8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Reworked re-attaching the shared memory after its concurrent deletion

This commit is contained in:
Dmitry Yemanov 2020-08-09 13:26:56 +03:00
parent 22ad236f62
commit b283d804d1
6 changed files with 55 additions and 65 deletions

View File

@ -174,7 +174,10 @@ struct event_t
class MemoryHeader
{
public:
static const USHORT HEADER_VERSION = 1;
static const USHORT HEADER_VERSION = 2;
// Values for mhb_flags
static const USHORT FLAG_DELETED = 1; // Shared file has been deleted
void init(USHORT type, USHORT version)
{
@ -182,15 +185,26 @@ public:
mhb_header_version = HEADER_VERSION;
mhb_version = version;
mhb_timestamp = TimeStamp::getCurrentTimeStamp().value();
mhb_flags = 0;
#ifdef HAVE_SHARED_MUTEX_SECTION
fb_assert(sizeof(mhb_mutex) <= sizeof(dummy));
#endif
}
void markAsDeleted()
{
mhb_flags |= FLAG_DELETED;
}
bool isDeleted() const
{
return (mhb_flags & FLAG_DELETED);
}
USHORT mhb_type;
USHORT mhb_header_version;
USHORT mhb_version;
USHORT reserve; // not used
USHORT mhb_flags;
GDS_TIMESTAMP mhb_timestamp;
union
{
@ -333,18 +347,6 @@ public:
// because there is no portable barrier semantics for them. Only MS2005+ generate
// barriers, and all other compilers generally do not.
bool justCreated()
{
if (sh_mem_just_created)
{
// complete initialization
sh_mem_just_created = false;
return true;
}
return false;
}
private:
#ifdef USE_SYS5SEMAPHORE
int fileNum; // file number in shared table of shared files
@ -353,7 +355,6 @@ private:
#endif
IpcObject* sh_mem_callback;
bool sh_mem_just_created;
#ifdef WIN_NT
bool sh_mem_unlink;
#endif

View File

@ -1734,11 +1734,15 @@ ULONG ISC_exception_post(ULONG except_code, const TEXT* err_msg, ISC_STATUS& isc
void SharedMemoryBase::removeMapFile()
{
fb_assert(sh_mem_header && !sh_mem_header->isDeleted());
#ifndef WIN_NT
unlinkFile();
#else
sh_mem_unlink = true;
#endif // WIN_NT
sh_mem_header->markAsDeleted();
}
void SharedMemoryBase::unlinkFile()
@ -1965,7 +1969,6 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
if (trunc_flag)
FB_UNUSED(os_utils::ftruncate(mainLock->getFd(), length));
sh_mem_just_created = true;
if (callback->initialize(this, true))
{
#ifdef HAVE_SHARED_MUTEX_SECTION
@ -2089,7 +2092,6 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
}
else
{
sh_mem_just_created = false;
if (callback->initialize(this, false))
{
if (!mainLock->setlock(&statusVector, FileLock::FLM_SHARED))
@ -2419,7 +2421,6 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
sh_mem_hdr_address = header_address;
strcpy(sh_mem_name, filename);
sh_mem_just_created = init_flag;
sh_mem_callback->initialize(this, init_flag);
if (init_flag)

View File

@ -166,7 +166,7 @@ MonitoringData::MonitoringData(Database* dbb)
MonitoringData::~MonitoringData()
{
m_sharedMemory->mutexLock();
Guard guard(this);
try
{
@ -178,8 +178,6 @@ MonitoringData::~MonitoringData()
}
catch (const Exception&)
{} // no-op
m_sharedMemory->mutexUnlock();
}
@ -210,12 +208,13 @@ void MonitoringData::acquire()
m_localMutex.enter(FB_FUNCTION);
m_sharedMemory->mutexLock();
while (m_sharedMemory->getHeader()->used == alignOffset(sizeof(Header)))
{
if (m_sharedMemory->justCreated())
break;
// Reattach if someone has just deleted the shared file
while (m_sharedMemory->getHeader()->isDeleted())
{
// Shared memory must be empty at this point
fb_assert(m_sharedMemory->getHeader()->used == alignOffset(sizeof(Header)));
// Someone is going to delete shared file? Reattach.
m_sharedMemory->mutexUnlock();
m_sharedMemory.reset();
@ -225,8 +224,6 @@ void MonitoringData::acquire()
m_sharedMemory->mutexLock();
}
fb_assert(!m_sharedMemory->justCreated());
if (m_sharedMemory->getHeader()->allocated > m_sharedMemory->sh_mem_length_mapped)
{
#ifdef HAVE_OBJECT_MAP

View File

@ -459,18 +459,17 @@ void EventManager::acquire_shmem()
m_sharedMemory->mutexLock();
// Check for shared memory state consistency
// Reattach if someone has just deleted the shared file
while (SRQ_EMPTY(m_sharedMemory->getHeader()->evh_processes))
while (m_sharedMemory->getHeader()->isDeleted())
{
fb_assert(!m_process);
if (m_process)
fb_utils::logAndDie("Process disappeared in EventManager::acquire_shmem");
if (m_sharedMemory->justCreated())
break;
// Shared memory must be empty at this point
fb_assert(SRQ_EMPTY(m_sharedMemory->getHeader()->evh_processes));
// Someone is going to delete shared file? Reattach.
m_sharedMemory->mutexUnlock();
m_sharedMemory.reset();
@ -480,8 +479,6 @@ void EventManager::acquire_shmem()
m_sharedMemory->mutexLock();
}
fb_assert(!m_sharedMemory->justCreated());
m_sharedMemory->getHeader()->evh_current_process = m_processOffset;
if (m_sharedMemory->getHeader()->evh_length > m_sharedMemory->sh_mem_length_mapped)

View File

@ -402,27 +402,25 @@ void ChangeLog::lockState()
m_localMutex.enter(FB_FUNCTION);
m_sharedMemory->mutexLock();
// Reattach if someone has just deleted the shared file
while (m_sharedMemory->getHeader()->isDeleted())
{
// Shared memory must be empty at this point
fb_assert(!m_sharedMemory->getHeader()->pidLower);
fb_assert(!m_sharedMemory->getHeader()->pidUpper);
m_sharedMemory->mutexUnlock();
m_sharedMemory.reset();
Thread::yield();
initSharedFile();
m_sharedMemory->mutexLock();
}
try
{
while (!m_sharedMemory->getHeader()->pidUpper)
{
fb_assert(!m_sharedMemory->getHeader()->pidLower);
if (m_sharedMemory->justCreated())
break;
// Someone is going to delete shared file? Reattach.
m_sharedMemory->mutexUnlock();
m_sharedMemory.reset();
Thread::yield();
initSharedFile();
m_sharedMemory->mutexLock();
}
fb_assert(!m_sharedMemory->justCreated());
const auto state = m_sharedMemory->getHeader();
if (m_segments.isEmpty() || state->segmentCount > m_segments.getCount())

View File

@ -1061,22 +1061,20 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
if (!locked)
m_sharedMemory->mutexLock();
// Check for shared memory state consistency
// Reattach if someone has just deleted the shared file
while (SRQ_EMPTY(m_sharedMemory->getHeader()->lhb_processes))
while (m_sharedMemory->getHeader()->isDeleted())
{
fb_assert(!m_process);
if (m_process)
bug(NULL, "Process disappeared in LockManager::acquire_shmem");
if (m_sharedMemory->justCreated())
{
// no sense thinking about statistics now
m_blockage = false;
break;
}
// Shared memory must be empty at this point
fb_assert(SRQ_EMPTY(m_sharedMemory->getHeader()->lhb_processes));
// no sense thinking about statistics now
m_blockage = false;
// Someone is going to delete shared file? Reattach.
m_sharedMemory->mutexUnlock();
m_sharedMemory.reset();
@ -1088,8 +1086,6 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
m_sharedMemory->mutexLock();
}
fb_assert(!m_sharedMemory->justCreated());
++(m_sharedMemory->getHeader()->lhb_acquires);
if (m_blockage)
{