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:
parent
22ad236f62
commit
b283d804d1
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user