mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 06:03:02 +01:00
1) Globally named per-database shmem regions.
2) Slightly reworked monitoring internals. 3) Encapsulated the event manager, many internal changes there. 4) Various cleanup, etc.
This commit is contained in:
parent
bb59a30d0f
commit
1b3927b026
@ -54,6 +54,28 @@ namespace Jrd
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Firebird::string& Database::getUniqueFileId() const
|
||||||
|
{
|
||||||
|
static Firebird::GlobalPtr<Firebird::string> file_id;
|
||||||
|
|
||||||
|
if (file_id->empty())
|
||||||
|
{
|
||||||
|
const PageSpace* const pageSpace = dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
|
|
||||||
|
Firebird::UCharBuffer buffer;
|
||||||
|
PIO_get_unique_file_id(pageSpace->file, buffer);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < buffer.getCount(); i++)
|
||||||
|
{
|
||||||
|
TEXT hex[3];
|
||||||
|
sprintf(hex, "%02x", (int) buffer[i]);
|
||||||
|
file_id->append(hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_id;
|
||||||
|
}
|
||||||
|
|
||||||
Database::~Database()
|
Database::~Database()
|
||||||
{
|
{
|
||||||
delete dbb_sys_trans;
|
delete dbb_sys_trans;
|
||||||
@ -66,9 +88,14 @@ namespace Jrd
|
|||||||
MemoryPool::deletePool(dbb_pools[i]);
|
MemoryPool::deletePool(dbb_pools[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete dbb_monitoring_data;
|
||||||
|
|
||||||
dbb_flags |= DBB_destroying;
|
dbb_flags |= DBB_destroying;
|
||||||
|
|
||||||
Checkout dcoHolder(this);
|
Checkout dcoHolder(this);
|
||||||
dbb_lock_mgr->release();
|
// This line decrements the usage counter and may cause the destructor to be called.
|
||||||
|
// It should happen with the dbb_sync unlocked.
|
||||||
|
dbb_lock_mgr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::deletePool(MemoryPool* pool)
|
void Database::deletePool(MemoryPool* pool)
|
||||||
|
@ -57,19 +57,20 @@
|
|||||||
#include "../common/classes/PublicHandle.h"
|
#include "../common/classes/PublicHandle.h"
|
||||||
#include "../common/classes/semaphore.h"
|
#include "../common/classes/semaphore.h"
|
||||||
#include "../common/utils_proto.h"
|
#include "../common/utils_proto.h"
|
||||||
|
#include "../jrd/DatabaseSnapshot.h"
|
||||||
#include "../jrd/RandomGenerator.h"
|
#include "../jrd/RandomGenerator.h"
|
||||||
#include "../jrd/os/guid.h"
|
#include "../jrd/os/guid.h"
|
||||||
#include "../jrd/sbm.h"
|
#include "../jrd/sbm.h"
|
||||||
#include "../jrd/flu.h"
|
#include "../jrd/flu.h"
|
||||||
#include "../jrd/RuntimeStatistics.h"
|
#include "../jrd/RuntimeStatistics.h"
|
||||||
#include "../lock/lock_proto.h"
|
|
||||||
#include "../jrd/os/thd_priority.h"
|
#include "../jrd/os/thd_priority.h"
|
||||||
|
#include "../jrd/event_proto.h"
|
||||||
|
#include "../lock/lock_proto.h"
|
||||||
|
|
||||||
class CharSetContainer;
|
class CharSetContainer;
|
||||||
|
|
||||||
namespace Jrd
|
namespace Jrd
|
||||||
{
|
{
|
||||||
|
|
||||||
class Trigger;
|
class Trigger;
|
||||||
template <typename T> class vec;
|
template <typename T> class vec;
|
||||||
class jrd_prc;
|
class jrd_prc;
|
||||||
@ -326,10 +327,10 @@ public:
|
|||||||
return TypedHandle<type_dbb>::checkHandle();
|
return TypedHandle<type_dbb>::checkHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable Sync* dbb_sync; // Database sync primitive
|
mutable Firebird::RefPtr<Sync> dbb_sync; // Database sync primitive
|
||||||
Firebird::Reference dbb_sync_ref; // Database reference to dbb_sync
|
|
||||||
|
|
||||||
LockManager* dbb_lock_mgr;
|
Firebird::RefPtr<LockManager> dbb_lock_mgr;
|
||||||
|
Firebird::RefPtr<EventManager> dbb_event_mgr;
|
||||||
|
|
||||||
Database* dbb_next; // Next database block in system
|
Database* dbb_next; // Next database block in system
|
||||||
Attachment* dbb_attachments; // Active attachments
|
Attachment* dbb_attachments; // Active attachments
|
||||||
@ -342,10 +343,8 @@ public:
|
|||||||
SLONG dbb_sh_counter_curr; // current value of shared counter lock
|
SLONG dbb_sh_counter_curr; // current value of shared counter lock
|
||||||
SLONG dbb_sh_counter_max; // maximum cached value of shared counter lock
|
SLONG dbb_sh_counter_max; // maximum cached value of shared counter lock
|
||||||
jrd_tra* dbb_sys_trans; // system transaction
|
jrd_tra* dbb_sys_trans; // system transaction
|
||||||
// jrd_file* dbb_file; // files for I/O operations
|
|
||||||
Shadow* dbb_shadow; // shadow control block
|
Shadow* dbb_shadow; // shadow control block
|
||||||
Lock* dbb_shadow_lock; // lock for synchronizing addition of shadows
|
Lock* dbb_shadow_lock; // lock for synchronizing addition of shadows
|
||||||
//SLONG dbb_shadow_sync_count; // to synchronize changes to shadows
|
|
||||||
Lock* dbb_retaining_lock; // lock for preserving commit retaining snapshot
|
Lock* dbb_retaining_lock; // lock for preserving commit retaining snapshot
|
||||||
Lock* dbb_monitor_lock; // lock for monitoring purposes
|
Lock* dbb_monitor_lock; // lock for monitoring purposes
|
||||||
PageManager dbb_page_manager;
|
PageManager dbb_page_manager;
|
||||||
@ -354,6 +353,8 @@ public:
|
|||||||
BlobFilter* dbb_blob_filters; // known blob filters
|
BlobFilter* dbb_blob_filters; // known blob filters
|
||||||
trig_vec* dbb_triggers[DB_TRIGGER_MAX];
|
trig_vec* dbb_triggers[DB_TRIGGER_MAX];
|
||||||
|
|
||||||
|
DatabaseSnapshot::SharedData* dbb_monitoring_data; // monitoring data
|
||||||
|
|
||||||
DatabaseModules dbb_modules; // external function/filter modules
|
DatabaseModules dbb_modules; // external function/filter modules
|
||||||
|
|
||||||
Firebird::Mutex dbb_meta_mutex; // Mutex to protect metadata changes while dbb_sync is unlocked
|
Firebird::Mutex dbb_meta_mutex; // Mutex to protect metadata changes while dbb_sync is unlocked
|
||||||
@ -447,6 +448,9 @@ public:
|
|||||||
// returns true if primary file is located on raw device
|
// returns true if primary file is located on raw device
|
||||||
bool onRawDevice() const;
|
bool onRawDevice() const;
|
||||||
|
|
||||||
|
// returns an unique ID string for a database file
|
||||||
|
const Firebird::string& getUniqueFileId() const;
|
||||||
|
|
||||||
MemoryPool* createPool()
|
MemoryPool* createPool()
|
||||||
{
|
{
|
||||||
MemoryPool* const pool = MemoryPool::createPool(dbb_permanent, dbb_memory_stats);
|
MemoryPool* const pool = MemoryPool::createPool(dbb_permanent, dbb_memory_stats);
|
||||||
@ -459,7 +463,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
explicit Database(MemoryPool* p)
|
explicit Database(MemoryPool* p)
|
||||||
: dbb_sync(FB_NEW(*getDefaultMemoryPool()) Sync),
|
: dbb_sync(FB_NEW(*getDefaultMemoryPool()) Sync),
|
||||||
dbb_sync_ref(*dbb_sync),
|
|
||||||
dbb_page_manager(*p),
|
dbb_page_manager(*p),
|
||||||
dbb_modules(*p),
|
dbb_modules(*p),
|
||||||
dbb_filename(*p),
|
dbb_filename(*p),
|
||||||
|
@ -72,35 +72,40 @@ const UCHAR TAG_RECORD = MAX_UCHAR;
|
|||||||
|
|
||||||
// SharedMemory class
|
// SharedMemory class
|
||||||
|
|
||||||
const ULONG DatabaseSnapshot::SharedMemory::VERSION = 2;
|
DatabaseSnapshot::SharedData::SharedData(const Database* dbb)
|
||||||
const ULONG DatabaseSnapshot::SharedMemory::DEFAULT_SIZE = 1048576;
|
: process_id(getpid()), local_id(dbb->dbb_monitoring_id)
|
||||||
|
|
||||||
|
|
||||||
DatabaseSnapshot::SharedMemory::SharedMemory()
|
|
||||||
{
|
{
|
||||||
TEXT filename[MAXPATHLEN];
|
Firebird::string name;
|
||||||
gds__prefix_lock(filename, MONITOR_FILE);
|
name.printf(MONITOR_FILE, dbb->getUniqueFileId().c_str());
|
||||||
|
|
||||||
ISC_STATUS_ARRAY statusVector;
|
ISC_STATUS_ARRAY statusVector;
|
||||||
base = (Header*) ISC_map_file(statusVector, filename, init, this, DEFAULT_SIZE, &handle);
|
base = (Header*) ISC_map_file(statusVector, name.c_str(), init, this, DEFAULT_SIZE, &handle);
|
||||||
if (!base)
|
if (!base)
|
||||||
{
|
{
|
||||||
iscLogStatus("Cannot initialize the shared memory region", statusVector);
|
iscLogStatus("Cannot initialize the shared memory region", statusVector);
|
||||||
status_exception::raise(statusVector);
|
status_exception::raise(statusVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(base->version == VERSION);
|
fb_assert(base->version == MONITOR_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DatabaseSnapshot::SharedMemory::~SharedMemory()
|
DatabaseSnapshot::SharedData::~SharedData()
|
||||||
{
|
{
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
#ifdef WIN_NT
|
||||||
|
ISC_mutex_fini(&mutex);
|
||||||
|
#else
|
||||||
|
ISC_mutex_fini(&base->mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
ISC_STATUS_ARRAY statusVector;
|
ISC_STATUS_ARRAY statusVector;
|
||||||
ISC_unmap_file(statusVector, &handle);
|
ISC_unmap_file(statusVector, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::acquire()
|
void DatabaseSnapshot::SharedData::acquire()
|
||||||
{
|
{
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
checkMutex("lock", ISC_mutex_lock(&mutex));
|
checkMutex("lock", ISC_mutex_lock(&mutex));
|
||||||
@ -123,7 +128,7 @@ void DatabaseSnapshot::SharedMemory::acquire()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::release()
|
void DatabaseSnapshot::SharedData::release()
|
||||||
{
|
{
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
checkMutex("unlock", ISC_mutex_unlock(&mutex));
|
checkMutex("unlock", ISC_mutex_unlock(&mutex));
|
||||||
@ -133,13 +138,8 @@ void DatabaseSnapshot::SharedMemory::release()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UCHAR* DatabaseSnapshot::SharedMemory::readData(thread_db* tdbb, MemoryPool& pool, ULONG& resultSize)
|
UCHAR* DatabaseSnapshot::SharedData::read(MemoryPool& pool, ULONG& resultSize)
|
||||||
{
|
{
|
||||||
fb_assert(tdbb);
|
|
||||||
|
|
||||||
const Database* const dbb = tdbb->getDatabase();
|
|
||||||
fb_assert(dbb);
|
|
||||||
|
|
||||||
DumpGuard guard(this);
|
DumpGuard guard(this);
|
||||||
|
|
||||||
ULONG self_dbb_offset = 0;
|
ULONG self_dbb_offset = 0;
|
||||||
@ -157,7 +157,7 @@ UCHAR* DatabaseSnapshot::SharedMemory::readData(thread_db* tdbb, MemoryPool& poo
|
|||||||
const Element* const element = (Element*) ptr;
|
const Element* const element = (Element*) ptr;
|
||||||
const ULONG length = sizeof(Element) + element->length;
|
const ULONG length = sizeof(Element) + element->length;
|
||||||
|
|
||||||
if (element->processId == getpid() && element->localId == dbb->dbb_monitoring_id)
|
if (element->processId == process_id && element->localId == local_id)
|
||||||
{
|
{
|
||||||
self_dbb_offset = offset;
|
self_dbb_offset = offset;
|
||||||
}
|
}
|
||||||
@ -206,17 +206,12 @@ UCHAR* DatabaseSnapshot::SharedMemory::readData(thread_db* tdbb, MemoryPool& poo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::writeData(thread_db* tdbb, ULONG length, const UCHAR* buffer)
|
void DatabaseSnapshot::SharedData::write(ULONG length, const UCHAR* buffer)
|
||||||
{
|
{
|
||||||
fb_assert(tdbb);
|
|
||||||
|
|
||||||
const Database* const dbb = tdbb->getDatabase();
|
|
||||||
fb_assert(dbb);
|
|
||||||
|
|
||||||
DumpGuard guard(this);
|
DumpGuard guard(this);
|
||||||
|
|
||||||
// Remove old copies of our element, if any
|
// Remove old copies of our element, if any
|
||||||
doCleanup(dbb);
|
cleanup();
|
||||||
|
|
||||||
// Do we need to extend the allocated memory?
|
// Do we need to extend the allocated memory?
|
||||||
while (base->used + sizeof(Element) + length > base->allocated)
|
while (base->used + sizeof(Element) + length > base->allocated)
|
||||||
@ -227,37 +222,24 @@ void DatabaseSnapshot::SharedMemory::writeData(thread_db* tdbb, ULONG length, co
|
|||||||
// Put an up-to-date element at the tail
|
// Put an up-to-date element at the tail
|
||||||
UCHAR* const ptr = (UCHAR*) base + base->used;
|
UCHAR* const ptr = (UCHAR*) base + base->used;
|
||||||
Element* const element = (Element*) ptr;
|
Element* const element = (Element*) ptr;
|
||||||
element->processId = getpid();
|
element->processId = process_id;
|
||||||
element->localId = dbb->dbb_monitoring_id;
|
element->localId = local_id;
|
||||||
element->length = length;
|
element->length = length;
|
||||||
memcpy(ptr + sizeof(Element), buffer, length);
|
memcpy(ptr + sizeof(Element), buffer, length);
|
||||||
base->used += sizeof(Element) + length;
|
base->used += sizeof(Element) + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::cleanup(thread_db* tdbb)
|
void DatabaseSnapshot::SharedData::cleanup()
|
||||||
{
|
{
|
||||||
fb_assert(tdbb);
|
|
||||||
|
|
||||||
const Database* const dbb = tdbb->getDatabase();
|
|
||||||
fb_assert(dbb);
|
|
||||||
|
|
||||||
DumpGuard guard(this);
|
|
||||||
|
|
||||||
// Remove information about our dbb
|
// Remove information about our dbb
|
||||||
doCleanup(dbb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::doCleanup(const Database* const dbb)
|
|
||||||
{
|
|
||||||
for (ULONG offset = sizeof(Header); offset < base->used;)
|
for (ULONG offset = sizeof(Header); offset < base->used;)
|
||||||
{
|
{
|
||||||
UCHAR* const ptr = (UCHAR*) base + offset;
|
UCHAR* const ptr = (UCHAR*) base + offset;
|
||||||
const Element* const element = (Element*) ptr;
|
const Element* const element = (Element*) ptr;
|
||||||
const ULONG length = sizeof(Element) + element->length;
|
const ULONG length = sizeof(Element) + element->length;
|
||||||
|
|
||||||
if (element->processId == getpid() && element->localId == dbb->dbb_monitoring_id)
|
if (element->processId == process_id && element->localId == local_id)
|
||||||
{
|
{
|
||||||
fb_assert(base->used >= offset + length);
|
fb_assert(base->used >= offset + length);
|
||||||
memmove(ptr, ptr + length, base->used - offset - length);
|
memmove(ptr, ptr + length, base->used - offset - length);
|
||||||
@ -271,7 +253,7 @@ void DatabaseSnapshot::SharedMemory::doCleanup(const Database* const dbb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::extend()
|
void DatabaseSnapshot::SharedData::extend()
|
||||||
{
|
{
|
||||||
const ULONG newSize = handle.sh_mem_length_mapped + DEFAULT_SIZE;
|
const ULONG newSize = handle.sh_mem_length_mapped + DEFAULT_SIZE;
|
||||||
|
|
||||||
@ -289,7 +271,7 @@ void DatabaseSnapshot::SharedMemory::extend()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::checkMutex(const TEXT* string, int state)
|
void DatabaseSnapshot::SharedData::checkMutex(const TEXT* string, int state)
|
||||||
{
|
{
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
@ -304,15 +286,13 @@ void DatabaseSnapshot::SharedMemory::checkMutex(const TEXT* string, int state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::SharedMemory::init(void* arg, SH_MEM_T* shmemData, bool initialize)
|
void DatabaseSnapshot::SharedData::init(void* arg, SH_MEM_T* shmemData, bool initialize)
|
||||||
{
|
{
|
||||||
SharedMemory* const shmem = (SharedMemory*) arg;
|
SharedData* const shmem = (SharedData*) arg;
|
||||||
fb_assert(shmem);
|
fb_assert(shmem);
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
char buffer[MAXPATHLEN];
|
checkMutex("init", ISC_mutex_init(&shmem->mutex, shmemData->sh_mem_name));
|
||||||
gds__prefix_lock(buffer, MONITOR_FILE);
|
|
||||||
checkMutex("init", ISC_mutex_init(&shmem->mutex, buffer));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!initialize)
|
if (!initialize)
|
||||||
@ -320,7 +300,7 @@ void DatabaseSnapshot::SharedMemory::init(void* arg, SH_MEM_T* shmemData, bool i
|
|||||||
|
|
||||||
// Initialize the shared data header
|
// Initialize the shared data header
|
||||||
Header* const header = (Header*) shmemData->sh_mem_address;
|
Header* const header = (Header*) shmemData->sh_mem_address;
|
||||||
header->version = VERSION;
|
header->version = MONITOR_VERSION;
|
||||||
header->used = sizeof(Header);
|
header->used = sizeof(Header);
|
||||||
header->allocated = shmemData->sh_mem_length_mapped;
|
header->allocated = shmemData->sh_mem_length_mapped;
|
||||||
|
|
||||||
@ -332,9 +312,6 @@ void DatabaseSnapshot::SharedMemory::init(void* arg, SH_MEM_T* shmemData, bool i
|
|||||||
|
|
||||||
// DatabaseSnapshot class
|
// DatabaseSnapshot class
|
||||||
|
|
||||||
DatabaseSnapshot::SharedMemory* DatabaseSnapshot::dump = NULL;
|
|
||||||
InitMutex<DatabaseSnapshot> DatabaseSnapshot::startup;
|
|
||||||
|
|
||||||
|
|
||||||
DatabaseSnapshot* DatabaseSnapshot::create(thread_db* tdbb)
|
DatabaseSnapshot* DatabaseSnapshot::create(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
@ -355,17 +332,6 @@ DatabaseSnapshot* DatabaseSnapshot::create(thread_db* tdbb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseSnapshot::cleanup(thread_db* tdbb)
|
|
||||||
{
|
|
||||||
SET_TDBB(tdbb);
|
|
||||||
|
|
||||||
if (dump)
|
|
||||||
{
|
|
||||||
dump->cleanup(tdbb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DatabaseSnapshot::blockingAst(void* ast_object)
|
int DatabaseSnapshot::blockingAst(void* ast_object)
|
||||||
{
|
{
|
||||||
Database* dbb = static_cast<Database*>(ast_object);
|
Database* dbb = static_cast<Database*>(ast_object);
|
||||||
@ -458,9 +424,9 @@ DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
|
|||||||
dbb->dbb_ast_flags |= DBB_monitor_off;
|
dbb->dbb_ast_flags |= DBB_monitor_off;
|
||||||
|
|
||||||
// Read the shared memory
|
// Read the shared memory
|
||||||
fb_assert(dump);
|
fb_assert(dbb->dbb_monitoring_data);
|
||||||
ULONG dataSize = 0;
|
ULONG dataSize = 0;
|
||||||
AutoPtr<UCHAR, ArrayDelete<UCHAR> > data(dump->readData(tdbb, pool, dataSize));
|
AutoPtr<UCHAR, ArrayDelete<UCHAR> > data(dbb->dbb_monitoring_data->read(pool, dataSize));
|
||||||
fb_assert(dataSize);
|
fb_assert(dataSize);
|
||||||
|
|
||||||
ClumpletReader reader(ClumpletReader::WideUnTagged, data, dataSize);
|
ClumpletReader reader(ClumpletReader::WideUnTagged, data, dataSize);
|
||||||
@ -899,10 +865,12 @@ void DatabaseSnapshot::dumpData(thread_db* tdbb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startup.init();
|
if (!dbb->dbb_monitoring_data)
|
||||||
|
{
|
||||||
|
dbb->dbb_monitoring_data = FB_NEW(*dbb->dbb_permanent) SharedData(dbb);
|
||||||
|
}
|
||||||
|
|
||||||
fb_assert(dump);
|
dbb->dbb_monitoring_data->write(writer.getBufferLength(), writer.getBuffer());
|
||||||
dump->writeData(tdbb, writer.getBufferLength(), writer.getBuffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
class jrd_rel;
|
||||||
|
class RecordBuffer;
|
||||||
|
class RuntimeStatistics;
|
||||||
|
|
||||||
class DatabaseSnapshot
|
class DatabaseSnapshot
|
||||||
{
|
{
|
||||||
struct RelationData
|
struct RelationData
|
||||||
@ -38,10 +43,18 @@ class DatabaseSnapshot
|
|||||||
RecordBuffer* data;
|
RecordBuffer* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedMemory
|
struct Element
|
||||||
{
|
{
|
||||||
static const ULONG VERSION;
|
SLONG processId;
|
||||||
static const ULONG DEFAULT_SIZE;
|
SLONG localId;
|
||||||
|
ULONG length;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
class SharedData
|
||||||
|
{
|
||||||
|
static const ULONG MONITOR_VERSION = 2;
|
||||||
|
static const ULONG DEFAULT_SIZE = 1048576;
|
||||||
|
|
||||||
struct Header
|
struct Header
|
||||||
{
|
{
|
||||||
@ -56,42 +69,40 @@ class DatabaseSnapshot
|
|||||||
class DumpGuard
|
class DumpGuard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DumpGuard(SharedMemory* ptr)
|
explicit DumpGuard(SharedData* ptr)
|
||||||
: dump(ptr)
|
: data(ptr)
|
||||||
{
|
{
|
||||||
dump->acquire();
|
data->acquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
~DumpGuard()
|
~DumpGuard()
|
||||||
{
|
{
|
||||||
dump->release();
|
data->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DumpGuard(const DumpGuard&);
|
DumpGuard(const DumpGuard&);
|
||||||
DumpGuard& operator=(const DumpGuard&);
|
DumpGuard& operator=(const DumpGuard&);
|
||||||
|
|
||||||
SharedMemory* dump;
|
SharedData* const data;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SharedMemory();
|
explicit SharedData(const Database*);
|
||||||
~SharedMemory();
|
~SharedData();
|
||||||
|
|
||||||
void acquire();
|
void acquire();
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
UCHAR* readData(thread_db*, MemoryPool&, ULONG&);
|
UCHAR* read(MemoryPool&, ULONG&);
|
||||||
void writeData(thread_db*, ULONG, const UCHAR*);
|
void write(ULONG, const UCHAR*);
|
||||||
|
|
||||||
void cleanup(thread_db*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// copying is prohibited
|
// copying is prohibited
|
||||||
SharedMemory(const SharedMemory&);
|
SharedData(const SharedData&);
|
||||||
SharedMemory& operator =(const SharedMemory&);
|
SharedData& operator =(const SharedData&);
|
||||||
|
|
||||||
void doCleanup(const Database* const dbb);
|
void cleanup();
|
||||||
void extend();
|
void extend();
|
||||||
|
|
||||||
static void checkMutex(const TEXT*, int);
|
static void checkMutex(const TEXT*, int);
|
||||||
@ -102,29 +113,18 @@ class DatabaseSnapshot
|
|||||||
struct mtx mutex;
|
struct mtx mutex;
|
||||||
#endif
|
#endif
|
||||||
Header* base;
|
Header* base;
|
||||||
|
|
||||||
|
const SLONG process_id;
|
||||||
|
const SLONG local_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Element
|
|
||||||
{
|
|
||||||
SLONG processId;
|
|
||||||
SLONG localId;
|
|
||||||
ULONG length;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
~DatabaseSnapshot();
|
~DatabaseSnapshot();
|
||||||
|
|
||||||
RecordBuffer* getData(const jrd_rel*) const;
|
RecordBuffer* getData(const jrd_rel*) const;
|
||||||
|
|
||||||
static DatabaseSnapshot* create(thread_db*);
|
static DatabaseSnapshot* create(thread_db*);
|
||||||
static void cleanup(thread_db*);
|
|
||||||
static int blockingAst(void*);
|
static int blockingAst(void*);
|
||||||
|
|
||||||
static void init()
|
|
||||||
{
|
|
||||||
dump = FB_NEW(*getDefaultMemoryPool()) SharedMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DatabaseSnapshot(thread_db*, MemoryPool&);
|
DatabaseSnapshot(thread_db*, MemoryPool&);
|
||||||
|
|
||||||
@ -147,9 +147,6 @@ private:
|
|||||||
static void putContextVars(Firebird::StringMap&, Firebird::ClumpletWriter&, int, bool);
|
static void putContextVars(Firebird::StringMap&, Firebird::ClumpletWriter&, int, bool);
|
||||||
static void putMemoryUsage(const Firebird::MemoryStats&, Firebird::ClumpletWriter&, int, int);
|
static void putMemoryUsage(const Firebird::MemoryStats&, Firebird::ClumpletWriter&, int, int);
|
||||||
|
|
||||||
static SharedMemory* dump;
|
|
||||||
static Firebird::InitMutex<DatabaseSnapshot> startup;
|
|
||||||
|
|
||||||
Firebird::Array<RelationData> snapshot;
|
Firebird::Array<RelationData> snapshot;
|
||||||
Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<SINT64, SLONG> > > idMap;
|
Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<SINT64, SLONG> > > idMap;
|
||||||
int idCounter;
|
int idCounter;
|
||||||
|
@ -634,8 +634,12 @@ void DFW_perform_post_commit_work(jrd_tra* transaction)
|
|||||||
switch (work->dfw_type)
|
switch (work->dfw_type)
|
||||||
{
|
{
|
||||||
case dfw_post_event:
|
case dfw_post_event:
|
||||||
EVENT_post(lock->lck_length, (const TEXT*) &lock->lck_key,
|
EventManager::init(dbb);
|
||||||
work->dfw_name.length(), work->dfw_name.c_str(), work->dfw_count);
|
|
||||||
|
dbb->dbb_event_mgr->postEvent(lock->lck_length, (const TEXT*) &lock->lck_key,
|
||||||
|
work->dfw_name.length(), work->dfw_name.c_str(),
|
||||||
|
work->dfw_count);
|
||||||
|
|
||||||
*ptr = work->dfw_next;
|
*ptr = work->dfw_next;
|
||||||
delete work;
|
delete work;
|
||||||
pending_events = true;
|
pending_events = true;
|
||||||
@ -651,7 +655,9 @@ void DFW_perform_post_commit_work(jrd_tra* transaction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pending_events)
|
if (pending_events)
|
||||||
EVENT_deliver();
|
{
|
||||||
|
dbb->dbb_event_mgr->deliverEvents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1188
src/jrd/event.cpp
1188
src/jrd/event.cpp
File diff suppressed because it is too large
Load Diff
@ -20,11 +20,7 @@
|
|||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
* Contributor(s): ______________________________________.
|
* Contributor(s): ______________________________________.
|
||||||
*
|
*
|
||||||
* 23-Feb-2002 Dmitry Yemanov - Events wildcarding
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 2002-02-23 Sean Leyne - Code Cleanup, removed old Win3.1 port (Windows_Only)
|
* 2002-02-23 Sean Leyne - Code Cleanup, removed old Win3.1 port (Windows_Only)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef JRD_EVENT_H
|
#ifndef JRD_EVENT_H
|
||||||
@ -36,16 +32,11 @@
|
|||||||
|
|
||||||
// Global section header
|
// Global section header
|
||||||
|
|
||||||
const int EVENT_VERSION = 4;
|
const int EVENT_VERSION = 4;
|
||||||
|
|
||||||
const int EVENT_HASH_SIZE = 7;
|
|
||||||
|
|
||||||
const int EVENT_DEFAULT_SIZE = 32768;
|
|
||||||
const int EVENT_EXTEND_SIZE = 32768;
|
|
||||||
|
|
||||||
struct evh
|
struct evh
|
||||||
{
|
{
|
||||||
SLONG evh_length; // Current length of global section
|
ULONG evh_length; // Current length of global section
|
||||||
UCHAR evh_version; // Version number of global section
|
UCHAR evh_version; // Version number of global section
|
||||||
srq evh_events; // Known events
|
srq evh_events; // Known events
|
||||||
srq evh_processes; // Known processes
|
srq evh_processes; // Known processes
|
||||||
@ -53,11 +44,8 @@ struct evh
|
|||||||
SRQ_PTR evh_current_process; // Current process, if any
|
SRQ_PTR evh_current_process; // Current process, if any
|
||||||
struct mtx evh_mutex; // Mutex controlling access
|
struct mtx evh_mutex; // Mutex controlling access
|
||||||
SLONG evh_request_id; // Next request id
|
SLONG evh_request_id; // Next request id
|
||||||
SRQ_PTR evh_hash_table[EVENT_HASH_SIZE];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef evh *EVH;
|
|
||||||
|
|
||||||
// Common block header
|
// Common block header
|
||||||
|
|
||||||
const int type_hdr = 1; // Event header
|
const int type_hdr = 1; // Event header
|
||||||
@ -71,7 +59,7 @@ const int type_max = 8;
|
|||||||
|
|
||||||
struct event_hdr // CVC: previous clash with ods.h's hdr
|
struct event_hdr // CVC: previous clash with ods.h's hdr
|
||||||
{
|
{
|
||||||
SLONG hdr_length; // Length of block
|
ULONG hdr_length; // Length of block
|
||||||
UCHAR hdr_type; // Type of block
|
UCHAR hdr_type; // Type of block
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,7 +70,6 @@ struct frb
|
|||||||
event_hdr frb_header;
|
event_hdr frb_header;
|
||||||
SLONG frb_next; // Next block
|
SLONG frb_next; // Next block
|
||||||
};
|
};
|
||||||
typedef frb *FRB;
|
|
||||||
|
|
||||||
// Process blocks
|
// Process blocks
|
||||||
|
|
||||||
@ -95,13 +82,13 @@ struct prb
|
|||||||
event_t prb_event; // Event on which to wait
|
event_t prb_event; // Event on which to wait
|
||||||
USHORT prb_flags;
|
USHORT prb_flags;
|
||||||
};
|
};
|
||||||
typedef prb *PRB;
|
|
||||||
|
|
||||||
const int PRB_wakeup = 1; // Schedule a wakeup for process
|
const int PRB_wakeup = 1; // Schedule a wakeup for process
|
||||||
const int PRB_pending = 2; // Wakeup has been requested, and is dangling
|
const int PRB_pending = 2; // Wakeup has been requested, and is dangling
|
||||||
|
#if (defined HAVE_MMAP || defined WIN_NT)
|
||||||
const int PRB_remap = 4; // need to remap shared memory
|
const int PRB_remap = 4; // need to remap shared memory
|
||||||
const int PRB_remap_over= 8; // remap is over
|
const int PRB_remap_over= 8; // remap is over
|
||||||
const int PRB_exiting = 16; // Process is exiting
|
#endif
|
||||||
|
|
||||||
// Session block
|
// Session block
|
||||||
|
|
||||||
@ -113,7 +100,6 @@ struct ses
|
|||||||
SRQ_PTR ses_interests; // Historical interests
|
SRQ_PTR ses_interests; // Historical interests
|
||||||
USHORT ses_flags;
|
USHORT ses_flags;
|
||||||
};
|
};
|
||||||
typedef ses *SES;
|
|
||||||
|
|
||||||
const int SES_delivering = 1; // Watcher thread is delivering an event
|
const int SES_delivering = 1; // Watcher thread is delivering an event
|
||||||
const int SES_purge = 2; // delete session after delivering an event
|
const int SES_purge = 2; // delete session after delivering an event
|
||||||
@ -130,7 +116,6 @@ struct evnt
|
|||||||
USHORT evnt_length; // Length of event name
|
USHORT evnt_length; // Length of event name
|
||||||
TEXT evnt_name[1]; // Event name
|
TEXT evnt_name[1]; // Event name
|
||||||
};
|
};
|
||||||
typedef evnt *EVNT;
|
|
||||||
|
|
||||||
// Request block
|
// Request block
|
||||||
|
|
||||||
@ -145,7 +130,6 @@ struct evt_req
|
|||||||
void *req_ast_arg; // Argument for ast
|
void *req_ast_arg; // Argument for ast
|
||||||
SLONG req_request_id; // Request id, dummy
|
SLONG req_request_id; // Request id, dummy
|
||||||
};
|
};
|
||||||
typedef evt_req *EVT_REQ;
|
|
||||||
|
|
||||||
// Request interest block
|
// Request interest block
|
||||||
|
|
||||||
@ -158,7 +142,6 @@ struct req_int
|
|||||||
SRQ_PTR rint_next; // Next interest of request
|
SRQ_PTR rint_next; // Next interest of request
|
||||||
SLONG rint_count; // Threshold count
|
SLONG rint_count; // Threshold count
|
||||||
};
|
};
|
||||||
typedef req_int *RINT;
|
|
||||||
|
|
||||||
const int EPB_version1 = 1;
|
const int EPB_version1 = 1;
|
||||||
|
|
||||||
|
@ -19,21 +19,102 @@
|
|||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
* Contributor(s): ______________________________________.
|
* Contributor(s): ______________________________________.
|
||||||
*
|
|
||||||
* 23-Feb-2002 Dmitry Yemanov - Events wildcarding
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef JRD_EVENT_PROTO_H
|
#ifndef JRD_EVENT_PROTO_H
|
||||||
#define JRD_EVENT_PROTO_H
|
#define JRD_EVENT_PROTO_H
|
||||||
|
|
||||||
void EVENT_cancel(SLONG);
|
#include "../common/classes/init.h"
|
||||||
SLONG EVENT_create_session();
|
#include "../common/classes/semaphore.h"
|
||||||
void EVENT_delete_session(SLONG);
|
#include "../common/classes/GenericMap.h"
|
||||||
void EVENT_deliver();
|
#include "../common/classes/RefCounted.h"
|
||||||
void EVENT_post(USHORT, const TEXT*, USHORT, const TEXT*, USHORT);
|
#include "../jrd/ThreadData.h"
|
||||||
SLONG EVENT_que(SLONG, USHORT, const TEXT*, USHORT, const UCHAR*,
|
#include "../jrd/event.h"
|
||||||
FPTR_EVENT_CALLBACK, void*);
|
|
||||||
|
namespace Jrd {
|
||||||
|
|
||||||
|
class Database;
|
||||||
|
|
||||||
|
class EventManager: public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||||
|
{
|
||||||
|
typedef Firebird::GenericMap<Firebird::Pair<Firebird::Left<Firebird::string, EventManager*> > > DbEventMgrMap;
|
||||||
|
|
||||||
|
static Firebird::GlobalPtr<DbEventMgrMap> g_emMap;
|
||||||
|
static Firebird::GlobalPtr<Firebird::Mutex> g_mapMutex;
|
||||||
|
|
||||||
|
const int PID;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void init(Database*);
|
||||||
|
|
||||||
|
explicit EventManager(const Firebird::string&);
|
||||||
|
~EventManager();
|
||||||
|
|
||||||
|
SLONG createSession();
|
||||||
|
void deleteSession(SLONG);
|
||||||
|
|
||||||
|
SLONG queEvents(SLONG, USHORT, const TEXT*, USHORT, const UCHAR*,
|
||||||
|
FPTR_EVENT_CALLBACK, void*);
|
||||||
|
void cancelEvents(SLONG);
|
||||||
|
void postEvent(USHORT, const TEXT*, USHORT, const TEXT*, USHORT);
|
||||||
|
void deliverEvents();
|
||||||
|
|
||||||
|
private:
|
||||||
|
evh* acquire_shmem();
|
||||||
|
frb* alloc_global(UCHAR type, ULONG length, bool recurse);
|
||||||
|
void create_process();
|
||||||
|
void delete_event(evnt*);
|
||||||
|
void delete_process(SLONG);
|
||||||
|
void delete_request(evt_req*);
|
||||||
|
void delete_session(SLONG);
|
||||||
|
void deliver();
|
||||||
|
void deliver_request(evt_req*);
|
||||||
|
void exit_handler(void *);
|
||||||
|
evnt* find_event(USHORT, const TEXT*, evnt*);
|
||||||
|
void free_global(frb*);
|
||||||
|
req_int* historical_interest(ses*, SLONG);
|
||||||
|
void init_shmem(SH_MEM, bool);
|
||||||
|
void insert_tail(srq*, srq*);
|
||||||
|
evnt* make_event(USHORT, const TEXT*, SLONG);
|
||||||
|
void post_process(prb*);
|
||||||
|
void probe_processes();
|
||||||
|
void release_shmem();
|
||||||
|
void remove_que(srq*);
|
||||||
|
bool request_completed(evt_req*);
|
||||||
|
void watcher_thread();
|
||||||
|
|
||||||
|
static THREAD_ENTRY_DECLARE watcher_thread(THREAD_ENTRY_PARAM arg)
|
||||||
|
{
|
||||||
|
EventManager* const eventMgr = static_cast<EventManager*>(arg);
|
||||||
|
eventMgr->watcher_thread();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_shmem(void* arg, SH_MEM shmem, bool init)
|
||||||
|
{
|
||||||
|
EventManager* const eventMgr = static_cast<EventManager*>(arg);
|
||||||
|
eventMgr->init_shmem(shmem, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mutex_bugcheck(const TEXT*, int);
|
||||||
|
static void punt(const TEXT*);
|
||||||
|
|
||||||
|
evh* m_header;
|
||||||
|
prb* m_process;
|
||||||
|
SLONG m_processOffset;
|
||||||
|
SH_MEM_T m_shmemData;
|
||||||
|
|
||||||
|
Firebird::string m_dbId;
|
||||||
|
|
||||||
|
Firebird::Semaphore m_startupSemaphore;
|
||||||
|
Firebird::Semaphore m_cleanupSemaphore;
|
||||||
|
|
||||||
|
#ifdef WIN_NT
|
||||||
|
struct mtx m_mutex;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
#endif // JRD_EVENT_PROTO_H
|
#endif // JRD_EVENT_PROTO_H
|
||||||
|
|
||||||
|
@ -32,27 +32,13 @@
|
|||||||
#ifndef JRD_FILE_PARAMS_H
|
#ifndef JRD_FILE_PARAMS_H
|
||||||
#define JRD_FILE_PARAMS_H
|
#define JRD_FILE_PARAMS_H
|
||||||
|
|
||||||
#ifdef NOHOSTNAME
|
static const char* EVENT_FILE = "fb_event_%s";
|
||||||
static const char* EVENT_FILE = "isc_event1";
|
static const char* LOCK_FILE = "fb_lock_%s";
|
||||||
static const char* LOCK_FILE = "isc_lock1.gbl";
|
static const char* MONITOR_FILE = "fb_monitor_%s";
|
||||||
static const char* INIT_FILE = "isc_init1";
|
|
||||||
static const char* GUARD_FILE = "isc_guard1";
|
#ifdef UNIX
|
||||||
static const char* MONITOR_FILE = "isc_monitor1";
|
static const char* INIT_FILE = "fb_init";
|
||||||
static const char* SEM_FILE = "isc_sem1";
|
static const char* SEM_FILE = "fb_sem";
|
||||||
#elif defined(WIN_NT)
|
|
||||||
static const char* EVENT_FILE = "%s.evn";
|
|
||||||
static const char* LOCK_FILE = "%s.lck";
|
|
||||||
static const char* INIT_FILE = "%s.int";
|
|
||||||
static const char* GUARD_FILE = "%s.grd";
|
|
||||||
static const char* MONITOR_FILE = "%s.mon";
|
|
||||||
static const char* SEM_FILE = "%s.sem";
|
|
||||||
#else
|
|
||||||
static const char* EVENT_FILE = "isc_event1.%s";
|
|
||||||
static const char* LOCK_FILE = "isc_lock1.%s";
|
|
||||||
static const char* INIT_FILE = "isc_init1.%s";
|
|
||||||
static const char* GUARD_FILE = "isc_guard1.%s";
|
|
||||||
static const char* MONITOR_FILE = "isc_monitor1.%s";
|
|
||||||
static const char* SEM_FILE = "isc_sem1.%s";
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CVC: Do we really need this information here after using autoconf?
|
// CVC: Do we really need this information here after using autoconf?
|
||||||
|
@ -3648,7 +3648,7 @@ public:
|
|||||||
Firebird::PathName lockPrefix;
|
Firebird::PathName lockPrefix;
|
||||||
if (!fb_utils::readenv(FB_LOCK_ENV, lockPrefix))
|
if (!fb_utils::readenv(FB_LOCK_ENV, lockPrefix))
|
||||||
{
|
{
|
||||||
lockPrefix = prefix;
|
lockPrefix = tempDir;
|
||||||
}
|
}
|
||||||
lockPrefix.copyTo(fb_prefix_lock_val, sizeof(fb_prefix_lock_val));
|
lockPrefix.copyTo(fb_prefix_lock_val, sizeof(fb_prefix_lock_val));
|
||||||
fb_prefix_lock = fb_prefix_lock_val;
|
fb_prefix_lock = fb_prefix_lock_val;
|
||||||
|
@ -880,20 +880,6 @@ bool INTL_defined_type(thread_db* tdbb, USHORT t_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void INTL_init(thread_db* tdbb)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* I N T L _ i n i t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
USHORT INTL_key_length(thread_db* tdbb, USHORT idxType, USHORT iLength)
|
USHORT INTL_key_length(thread_db* tdbb, USHORT idxType, USHORT iLength)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -43,7 +43,6 @@ int INTL_convert_string(dsc*, const dsc*, ErrorFunction);
|
|||||||
int INTL_data(const dsc*);
|
int INTL_data(const dsc*);
|
||||||
int INTL_data_or_binary(const dsc*);
|
int INTL_data_or_binary(const dsc*);
|
||||||
bool INTL_defined_type(Jrd::thread_db*, USHORT);
|
bool INTL_defined_type(Jrd::thread_db*, USHORT);
|
||||||
void INTL_init(Jrd::thread_db*);
|
|
||||||
USHORT INTL_key_length(Jrd::thread_db*, USHORT, USHORT);
|
USHORT INTL_key_length(Jrd::thread_db*, USHORT, USHORT);
|
||||||
Jrd::CharSet* INTL_charset_lookup(Jrd::thread_db* tdbb, USHORT parm1);
|
Jrd::CharSet* INTL_charset_lookup(Jrd::thread_db* tdbb, USHORT parm1);
|
||||||
Jrd::Collation* INTL_texttype_lookup(Jrd::thread_db* tdbb, USHORT parm1);
|
Jrd::Collation* INTL_texttype_lookup(Jrd::thread_db* tdbb, USHORT parm1);
|
||||||
|
@ -153,7 +153,7 @@ struct sh_mem
|
|||||||
void* sh_mem_object;
|
void* sh_mem_object;
|
||||||
void* sh_mem_interest;
|
void* sh_mem_interest;
|
||||||
void* sh_mem_hdr_object;
|
void* sh_mem_hdr_object;
|
||||||
SLONG* sh_mem_hdr_address;
|
ULONG* sh_mem_hdr_address;
|
||||||
TEXT sh_mem_name[MAXPATHLEN];
|
TEXT sh_mem_name[MAXPATHLEN];
|
||||||
};
|
};
|
||||||
typedef sh_mem SH_MEM_T;
|
typedef sh_mem SH_MEM_T;
|
||||||
|
@ -45,7 +45,7 @@ void* ISC_make_signal(bool, bool, int, int);
|
|||||||
|
|
||||||
typedef void (*FPTR_INIT_GLOBAL_REGION)(void*, struct sh_mem*, bool);
|
typedef void (*FPTR_INIT_GLOBAL_REGION)(void*, struct sh_mem*, bool);
|
||||||
UCHAR* ISC_map_file(ISC_STATUS*, const TEXT*, FPTR_INIT_GLOBAL_REGION,
|
UCHAR* ISC_map_file(ISC_STATUS*, const TEXT*, FPTR_INIT_GLOBAL_REGION,
|
||||||
void*, SLONG, struct sh_mem*);
|
void*, ULONG, struct sh_mem*);
|
||||||
#if defined(WIN_NT)
|
#if defined(WIN_NT)
|
||||||
int ISC_mutex_init(struct mtx*, const TEXT*);
|
int ISC_mutex_init(struct mtx*, const TEXT*);
|
||||||
#else
|
#else
|
||||||
@ -58,8 +58,8 @@ int ISC_mutex_unlock(struct mtx *);
|
|||||||
void ISC_mutex_fini(struct mtx *);
|
void ISC_mutex_fini(struct mtx *);
|
||||||
|
|
||||||
#if defined HAVE_MMAP || defined WIN_NT
|
#if defined HAVE_MMAP || defined WIN_NT
|
||||||
UCHAR* ISC_map_object(ISC_STATUS *, SH_MEM, SLONG, SLONG);
|
UCHAR* ISC_map_object(ISC_STATUS *, SH_MEM, ULONG, ULONG);
|
||||||
void ISC_unmap_object(ISC_STATUS *, SH_MEM, UCHAR **, SLONG);
|
void ISC_unmap_object(ISC_STATUS *, SH_MEM, UCHAR **, ULONG);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
@ -72,7 +72,7 @@ void ISC_sync_signals_reset();
|
|||||||
ULONG ISC_exception_post(ULONG, const TEXT*);
|
ULONG ISC_exception_post(ULONG, const TEXT*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UCHAR* ISC_remap_file(ISC_STATUS *, struct sh_mem *, SLONG, bool);
|
UCHAR* ISC_remap_file(ISC_STATUS *, struct sh_mem *, ULONG, bool);
|
||||||
void ISC_reset_timer(FPTR_VOID_PTR, void *, SLONG *, void **);
|
void ISC_reset_timer(FPTR_VOID_PTR, void *, SLONG *, void **);
|
||||||
void ISC_set_timer(SLONG, FPTR_VOID_PTR, void *, SLONG *, void **);
|
void ISC_set_timer(SLONG, FPTR_VOID_PTR, void *, SLONG *, void **);
|
||||||
void ISC_unmap_file(ISC_STATUS *, struct sh_mem *);
|
void ISC_unmap_file(ISC_STATUS *, struct sh_mem *);
|
||||||
|
@ -131,7 +131,7 @@ union semun
|
|||||||
ushort *array;
|
ushort *array;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif /* UNIX */
|
#endif // UNIX
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -1889,7 +1889,9 @@ void *ISC_make_signal(bool create_flag, bool manual_reset, int process_idL, int
|
|||||||
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
||||||
const TEXT* filename,
|
const TEXT* filename,
|
||||||
FPTR_INIT_GLOBAL_REGION init_routine,
|
FPTR_INIT_GLOBAL_REGION init_routine,
|
||||||
void* init_arg, SLONG length, SH_MEM shmem_data)
|
void* init_arg,
|
||||||
|
ULONG length,
|
||||||
|
SH_MEM shmem_data)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1903,25 +1905,20 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
* routine (if given) or punt (leaving the file unmapped).
|
* routine (if given) or punt (leaving the file unmapped).
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT expanded_filename[MAXPATHLEN], hostname[64];
|
|
||||||
sprintf(expanded_filename, filename, ISC_get_host(hostname, sizeof(hostname)));
|
TEXT expanded_filename[MAXPATHLEN];
|
||||||
|
gds__prefix_lock(expanded_filename, filename);
|
||||||
|
|
||||||
/* make the complete filename for the init file this file is to be used as a
|
/* make the complete filename for the init file this file is to be used as a
|
||||||
master lock to eliminate possible race conditions with just a single file
|
master lock to eliminate possible race conditions with just a single file
|
||||||
locking. The race condition is caused as the conversion of a EXCLUSIVE
|
locking. The race condition is caused as the conversion of a EXCLUSIVE
|
||||||
lock to a SHARED lock is not atomic*/
|
lock to a SHARED lock is not atomic*/
|
||||||
|
|
||||||
TEXT tmp[MAXPATHLEN];
|
TEXT init_filename[MAXPATHLEN];
|
||||||
gds__prefix_lock(tmp, INIT_FILE);
|
gds__prefix_lock(init_filename, INIT_FILE);
|
||||||
string init_filename; /* to hold the complete filename of the init file. */
|
|
||||||
init_filename.printf(tmp, hostname); /* already have the hostname! */
|
|
||||||
|
|
||||||
const int oldmask = umask(0);
|
const int oldmask = umask(0);
|
||||||
bool trunc_flag = true;
|
const bool trunc_flag = (length != 0);
|
||||||
if (length < 0) {
|
|
||||||
length = -length;
|
|
||||||
trunc_flag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the init lock file */
|
/* open the init lock file */
|
||||||
MutexLockGuard guard(openFdInit);
|
MutexLockGuard guard(openFdInit);
|
||||||
@ -1931,7 +1928,7 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
#endif
|
#endif
|
||||||
fd_init = open(init_filename.c_str(), O_RDWR | O_CREAT, 0666);
|
fd_init = open(init_filename, O_RDWR | O_CREAT, 0666);
|
||||||
if (fd_init == -1) {
|
if (fd_init == -1) {
|
||||||
error(status_vector, "open", errno);
|
error(status_vector, "open", errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1950,10 +1947,9 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
#ifdef USE_SYS5SEMAPHORE
|
#ifdef USE_SYS5SEMAPHORE
|
||||||
if (fdSem < 0)
|
if (fdSem < 0)
|
||||||
{
|
{
|
||||||
string semFileName;
|
TEXT sem_filename[MAXPATHLEN];
|
||||||
gds__prefix_lock(tmp, SEM_FILE);
|
gds__prefix_lock(sem_filename, SEM_FILE);
|
||||||
semFileName.printf(tmp, hostname);
|
int f = open(sem_filename, O_RDWR | O_CREAT, 0666);
|
||||||
int f = open(semFileName.c_str(), O_RDWR | O_CREAT, 0666);
|
|
||||||
if (f == -1) {
|
if (f == -1) {
|
||||||
error(status_vector, "open", errno);
|
error(status_vector, "open", errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2098,7 +2094,9 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
||||||
const TEXT* filename,
|
const TEXT* filename,
|
||||||
FPTR_INIT_GLOBAL_REGION init_routine,
|
FPTR_INIT_GLOBAL_REGION init_routine,
|
||||||
void* init_arg, SLONG length, SH_MEM shmem_data)
|
void* init_arg,
|
||||||
|
ULONG length,
|
||||||
|
SH_MEM shmem_data)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2112,18 +2110,12 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
* routine (if given) or punt (leaving the file unmapped).
|
* routine (if given) or punt (leaving the file unmapped).
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
//SSHORT count;
|
|
||||||
TEXT expanded_filename[512];
|
TEXT expanded_filename[MAXPATHLEN];
|
||||||
#ifdef NOHOSTNAME
|
gds__prefix_lock(expanded_filename, filename);
|
||||||
strcpy(expanded_filename, filename);
|
|
||||||
#else
|
|
||||||
TEXT hostname[64];
|
|
||||||
sprintf(expanded_filename, filename, ISC_get_host(hostname, sizeof(hostname)));
|
|
||||||
#endif
|
|
||||||
const int oldmask = umask(0);
|
const int oldmask = umask(0);
|
||||||
bool init_flag = false;
|
bool init_flag = false;
|
||||||
if (length < 0)
|
|
||||||
length = -length;
|
|
||||||
|
|
||||||
/* Produce shared memory key for file */
|
/* Produce shared memory key for file */
|
||||||
|
|
||||||
@ -2383,13 +2375,12 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
UCHAR* ISC_map_file(
|
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
||||||
ISC_STATUS* status_vector,
|
const TEXT* filename,
|
||||||
const TEXT* filename,
|
FPTR_INIT_GLOBAL_REGION init_routine,
|
||||||
FPTR_INIT_GLOBAL_REGION init_routine,
|
void* init_arg,
|
||||||
void* init_arg,
|
ULONG length,
|
||||||
SLONG length,
|
SH_MEM shmem_data)
|
||||||
SH_MEM shmem_data)
|
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2403,17 +2394,14 @@ UCHAR* ISC_map_file(
|
|||||||
* routine (if given) or punt (leaving the file unmapped).
|
* routine (if given) or punt (leaving the file unmapped).
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT expanded_filename[MAXPATHLEN], hostname[64];
|
TEXT object_name[MAXPATHLEN];
|
||||||
TEXT map_file[MAXPATHLEN];
|
|
||||||
HANDLE file_handle, event_handle;
|
HANDLE file_handle, event_handle;
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
|
|
||||||
bool trunc_flag = true;
|
TEXT expanded_filename[MAXPATHLEN];
|
||||||
if (length < 0) {
|
gds__prefix_lock(expanded_filename, filename);
|
||||||
length = -length;
|
|
||||||
fb_assert(length > 0); // Was someone so crazy as to pass a bigger value than MAX_SLONG?
|
const bool trunc_flag = (length != 0);
|
||||||
trunc_flag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* retry to attach to mmapped file if the process initializing
|
/* retry to attach to mmapped file if the process initializing
|
||||||
* dies during initialization.
|
* dies during initialization.
|
||||||
@ -2422,16 +2410,13 @@ UCHAR* ISC_map_file(
|
|||||||
retry:
|
retry:
|
||||||
retry_count++;
|
retry_count++;
|
||||||
|
|
||||||
ISC_get_host(hostname, sizeof(hostname));
|
file_handle = CreateFile(expanded_filename,
|
||||||
sprintf(map_file, filename, hostname);
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
file_handle = CreateFile(map_file,
|
NULL,
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
OPEN_ALWAYS,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL,
|
NULL);
|
||||||
OPEN_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||||
error(status_vector, "CreateFile", GetLastError());
|
error(status_vector, "CreateFile", GetLastError());
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2444,14 +2429,14 @@ UCHAR* ISC_map_file(
|
|||||||
// Create an event that can be used to determine if someone has already
|
// Create an event that can be used to determine if someone has already
|
||||||
// initialized shared memory.
|
// initialized shared memory.
|
||||||
|
|
||||||
if (!make_object_name(expanded_filename, sizeof(expanded_filename), filename, "_event"))
|
if (!make_object_name(object_name, sizeof(object_name), filename, "_event"))
|
||||||
{
|
{
|
||||||
error(status_vector, "make_object_name", GetLastError());
|
error(status_vector, "make_object_name", GetLastError());
|
||||||
CloseHandle(file_handle);
|
CloseHandle(file_handle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_handle = CreateEvent(ISC_get_security_desc(), TRUE, FALSE, expanded_filename);
|
event_handle = CreateEvent(ISC_get_security_desc(), TRUE, FALSE, object_name);
|
||||||
if (!event_handle) {
|
if (!event_handle) {
|
||||||
error(status_vector, "CreateEvent", GetLastError());
|
error(status_vector, "CreateEvent", GetLastError());
|
||||||
CloseHandle(file_handle);
|
CloseHandle(file_handle);
|
||||||
@ -2512,13 +2497,13 @@ UCHAR* ISC_map_file(
|
|||||||
else
|
else
|
||||||
fdw_create = OPEN_ALWAYS;
|
fdw_create = OPEN_ALWAYS;
|
||||||
|
|
||||||
file_handle = CreateFile(map_file,
|
file_handle = CreateFile(expanded_filename,
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
fdw_create,
|
fdw_create,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
error(status_vector, "CreateFile", GetLastError());
|
error(status_vector, "CreateFile", GetLastError());
|
||||||
@ -2528,7 +2513,7 @@ UCHAR* ISC_map_file(
|
|||||||
/* Create a file mapping object that will be used to make remapping possible.
|
/* Create a file mapping object that will be used to make remapping possible.
|
||||||
The current length of real mapped file and its name are saved in it. */
|
The current length of real mapped file and its name are saved in it. */
|
||||||
|
|
||||||
if (!make_object_name(expanded_filename, sizeof(expanded_filename), filename, "_mapping"))
|
if (!make_object_name(object_name, sizeof(object_name), filename, "_mapping"))
|
||||||
{
|
{
|
||||||
error(status_vector, "make_object_name", GetLastError());
|
error(status_vector, "make_object_name", GetLastError());
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
@ -2536,12 +2521,11 @@ UCHAR* ISC_map_file(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE header_obj = CreateFileMapping ((HANDLE) -1,
|
HANDLE header_obj = CreateFileMapping(INVALID_HANDLE_VALUE,
|
||||||
ISC_get_security_desc(),
|
ISC_get_security_desc(),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
0,
|
0, 2 * sizeof(ULONG),
|
||||||
2 * sizeof (SLONG),
|
object_name);
|
||||||
expanded_filename);
|
|
||||||
if (header_obj == NULL)
|
if (header_obj == NULL)
|
||||||
{
|
{
|
||||||
error(status_vector, "CreateFileMapping", GetLastError());
|
error(status_vector, "CreateFileMapping", GetLastError());
|
||||||
@ -2561,7 +2545,7 @@ UCHAR* ISC_map_file(
|
|||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLONG* const header_address = (SLONG*) MapViewOfFile(header_obj, FILE_MAP_WRITE, 0, 0, 0);
|
ULONG* const header_address = (ULONG*) MapViewOfFile(header_obj, FILE_MAP_WRITE, 0, 0, 0);
|
||||||
|
|
||||||
if (header_address == NULL) {
|
if (header_address == NULL) {
|
||||||
error(status_vector, "MapViewOfFile", GetLastError());
|
error(status_vector, "MapViewOfFile", GetLastError());
|
||||||
@ -2583,16 +2567,14 @@ UCHAR* ISC_map_file(
|
|||||||
|
|
||||||
/* Create the real file mapping object. */
|
/* Create the real file mapping object. */
|
||||||
|
|
||||||
TEXT mapping_filename[sizeof(expanded_filename) + 15]; // enough for int32 as text
|
TEXT mapping_name[MAXPATHLEN + 15]; // enough for int32 as text
|
||||||
sprintf(mapping_filename, "%s%"SLONGFORMAT, expanded_filename, header_address[1]);
|
sprintf(mapping_name, "%s_mapping_%"ULONGFORMAT, filename, header_address[1]);
|
||||||
|
|
||||||
HANDLE file_obj =
|
HANDLE file_obj = CreateFileMapping(file_handle,
|
||||||
CreateFileMapping(file_handle,
|
ISC_get_security_desc(),
|
||||||
ISC_get_security_desc(),
|
PAGE_READWRITE,
|
||||||
PAGE_READWRITE,
|
0, length,
|
||||||
0,
|
mapping_name);
|
||||||
length,
|
|
||||||
mapping_filename);
|
|
||||||
if (file_obj == NULL) {
|
if (file_obj == NULL) {
|
||||||
error(status_vector, "CreateFileMapping", GetLastError());
|
error(status_vector, "CreateFileMapping", GetLastError());
|
||||||
UnmapViewOfFile(header_address);
|
UnmapViewOfFile(header_address);
|
||||||
@ -2628,7 +2610,7 @@ UCHAR* ISC_map_file(
|
|||||||
shmem_data->sh_mem_interest = event_handle;
|
shmem_data->sh_mem_interest = event_handle;
|
||||||
shmem_data->sh_mem_hdr_object = header_obj;
|
shmem_data->sh_mem_hdr_object = header_obj;
|
||||||
shmem_data->sh_mem_hdr_address = header_address;
|
shmem_data->sh_mem_hdr_address = header_address;
|
||||||
strcpy(shmem_data->sh_mem_name, expanded_filename);
|
strcpy(shmem_data->sh_mem_name, filename);
|
||||||
|
|
||||||
if (init_routine)
|
if (init_routine)
|
||||||
(*init_routine) (init_arg, shmem_data, init_flag);
|
(*init_routine) (init_arg, shmem_data, init_flag);
|
||||||
@ -2636,7 +2618,7 @@ UCHAR* ISC_map_file(
|
|||||||
if (init_flag) {
|
if (init_flag) {
|
||||||
FlushViewOfFile(address, 0);
|
FlushViewOfFile(address, 0);
|
||||||
SetEvent(event_handle);
|
SetEvent(event_handle);
|
||||||
if (SetFilePointer(shmem_data->sh_mem_handle, length, NULL, FILE_BEGIN) == 0xFFFFFFFF ||
|
if (SetFilePointer(shmem_data->sh_mem_handle, length, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
|
||||||
!SetEndOfFile(shmem_data->sh_mem_handle) ||
|
!SetEndOfFile(shmem_data->sh_mem_handle) ||
|
||||||
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
|
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
|
||||||
{
|
{
|
||||||
@ -2651,9 +2633,10 @@ UCHAR* ISC_map_file(
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
UCHAR *ISC_map_object(ISC_STATUS * status_vector,
|
UCHAR* ISC_map_object(ISC_STATUS* status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
SLONG object_offset, SLONG object_length)
|
ULONG object_offset,
|
||||||
|
ULONG object_length)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2668,13 +2651,13 @@ UCHAR *ISC_map_object(ISC_STATUS * status_vector,
|
|||||||
/* Get system page size as this is the unit of mapping. */
|
/* Get system page size as this is the unit of mapping. */
|
||||||
|
|
||||||
#ifdef SOLARIS
|
#ifdef SOLARIS
|
||||||
const SLONG page_size = sysconf(_SC_PAGESIZE);
|
const ULONG page_size = sysconf(_SC_PAGESIZE);
|
||||||
if (page_size == -1) {
|
if (page_size == -1) {
|
||||||
error(status_vector, "sysconf", errno);
|
error(status_vector, "sysconf", errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
const SLONG page_size = (int) getpagesize();
|
const ULONG page_size = (int) getpagesize();
|
||||||
if (page_size == -1) {
|
if (page_size == -1) {
|
||||||
error(status_vector, "getpagesize", errno);
|
error(status_vector, "getpagesize", errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2684,9 +2667,9 @@ UCHAR *ISC_map_object(ISC_STATUS * status_vector,
|
|||||||
/* Compute the start and end page-aligned offsets which
|
/* Compute the start and end page-aligned offsets which
|
||||||
contain the object being mapped. */
|
contain the object being mapped. */
|
||||||
|
|
||||||
const SLONG start = (object_offset / page_size) * page_size;
|
const ULONG start = (object_offset / page_size) * page_size;
|
||||||
const SLONG end = (((object_offset + object_length) / page_size) + 1) * page_size;
|
const ULONG end = FB_ALIGN(object_offset + object_length, page_size);
|
||||||
const SLONG length = end - start;
|
const ULONG length = end - start;
|
||||||
int fd = shmem_data->sh_mem_handle;
|
int fd = shmem_data->sh_mem_handle;
|
||||||
|
|
||||||
UCHAR* address = (UCHAR*) mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
|
UCHAR* address = (UCHAR*) mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
|
||||||
@ -2706,7 +2689,8 @@ UCHAR *ISC_map_object(ISC_STATUS * status_vector,
|
|||||||
|
|
||||||
void ISC_unmap_object(ISC_STATUS* status_vector,
|
void ISC_unmap_object(ISC_STATUS* status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
UCHAR** object_pointer, SLONG object_length)
|
UCHAR** object_pointer,
|
||||||
|
ULONG object_length)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2722,13 +2706,13 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
|
|||||||
/* Get system page size as this is the unit of mapping. */
|
/* Get system page size as this is the unit of mapping. */
|
||||||
|
|
||||||
#ifdef SOLARIS
|
#ifdef SOLARIS
|
||||||
const SLONG page_size = sysconf(_SC_PAGESIZE);
|
const ULONG page_size = sysconf(_SC_PAGESIZE);
|
||||||
if (page_size == -1) {
|
if (page_size == -1) {
|
||||||
error(status_vector, "sysconf", errno);
|
error(status_vector, "sysconf", errno);
|
||||||
return; // false;
|
return; // false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
const SLONG page_size = (int) getpagesize();
|
const ULONG page_size = (int) getpagesize();
|
||||||
if (page_size == -1) {
|
if (page_size == -1) {
|
||||||
error(status_vector, "getpagesize", errno);
|
error(status_vector, "getpagesize", errno);
|
||||||
return; // false;
|
return; // false;
|
||||||
@ -2741,7 +2725,7 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
|
|||||||
UCHAR* start = (UCHAR *) ((U_IPTR) * object_pointer & ~(page_size - 1));
|
UCHAR* start = (UCHAR *) ((U_IPTR) * object_pointer & ~(page_size - 1));
|
||||||
const UCHAR* end =
|
const UCHAR* end =
|
||||||
(UCHAR*) ((U_IPTR) ((*object_pointer + object_length) + (page_size - 1)) & ~(page_size - 1));
|
(UCHAR*) ((U_IPTR) ((*object_pointer + object_length) + (page_size - 1)) & ~(page_size - 1));
|
||||||
const SLONG length = end - start;
|
const ULONG length = end - start;
|
||||||
|
|
||||||
if (munmap((char *) start, length) == -1) {
|
if (munmap((char *) start, length) == -1) {
|
||||||
error(status_vector, "munmap", errno);
|
error(status_vector, "munmap", errno);
|
||||||
@ -2757,7 +2741,8 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
|
|||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
UCHAR* ISC_map_object(ISC_STATUS* status_vector,
|
UCHAR* ISC_map_object(ISC_STATUS* status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
SLONG object_offset, SLONG object_length)
|
ULONG object_offset,
|
||||||
|
ULONG object_length)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2772,14 +2757,14 @@ UCHAR* ISC_map_object(ISC_STATUS* status_vector,
|
|||||||
|
|
||||||
SYSTEM_INFO sys_info;
|
SYSTEM_INFO sys_info;
|
||||||
GetSystemInfo(&sys_info);
|
GetSystemInfo(&sys_info);
|
||||||
const SLONG page_size = sys_info.dwAllocationGranularity;
|
const ULONG page_size = sys_info.dwAllocationGranularity;
|
||||||
|
|
||||||
// Compute the start and end page-aligned offsets which
|
// Compute the start and end page-aligned offsets which
|
||||||
// contain the object being mapped.
|
// contain the object being mapped.
|
||||||
|
|
||||||
const SLONG start = (object_offset / page_size) * page_size;
|
const ULONG start = (object_offset / page_size) * page_size;
|
||||||
const SLONG end = (((object_offset + object_length) / page_size) + 1) * page_size;
|
const ULONG end = FB_ALIGN(object_offset + object_length, page_size);
|
||||||
const SLONG length = end - start;
|
const ULONG length = end - start;
|
||||||
const HANDLE handle = shmem_data->sh_mem_object;
|
const HANDLE handle = shmem_data->sh_mem_object;
|
||||||
|
|
||||||
UCHAR* address = (UCHAR*) MapViewOfFile(handle, FILE_MAP_WRITE, 0, start, length);
|
UCHAR* address = (UCHAR*) MapViewOfFile(handle, FILE_MAP_WRITE, 0, start, length);
|
||||||
@ -2797,7 +2782,8 @@ UCHAR* ISC_map_object(ISC_STATUS* status_vector,
|
|||||||
|
|
||||||
void ISC_unmap_object(ISC_STATUS* status_vector,
|
void ISC_unmap_object(ISC_STATUS* status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
UCHAR** object_pointer, SLONG object_length)
|
UCHAR** object_pointer,
|
||||||
|
ULONG object_length)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -2812,7 +2798,7 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
|
|||||||
**************************************/
|
**************************************/
|
||||||
SYSTEM_INFO sys_info;
|
SYSTEM_INFO sys_info;
|
||||||
GetSystemInfo(&sys_info);
|
GetSystemInfo(&sys_info);
|
||||||
const SLONG page_size = sys_info.dwAllocationGranularity;
|
const ULONG page_size = sys_info.dwAllocationGranularity;
|
||||||
|
|
||||||
// Compute the start and end page-aligned offsets which
|
// Compute the start and end page-aligned offsets which
|
||||||
// contain the object being mapped.
|
// contain the object being mapped.
|
||||||
@ -3623,8 +3609,10 @@ void ISC_mutex_set_spin_count (struct mtx *mutex, ULONG spins)
|
|||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
#define ISC_REMAP_FILE_DEFINED
|
#define ISC_REMAP_FILE_DEFINED
|
||||||
UCHAR *ISC_remap_file(ISC_STATUS * status_vector,
|
UCHAR *ISC_remap_file(ISC_STATUS* status_vector,
|
||||||
SH_MEM shmem_data, SLONG new_length, bool flag)
|
SH_MEM shmem_data,
|
||||||
|
ULONG new_length,
|
||||||
|
bool flag)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -3669,9 +3657,9 @@ UCHAR *ISC_remap_file(ISC_STATUS * status_vector,
|
|||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
#define ISC_REMAP_FILE_DEFINED
|
#define ISC_REMAP_FILE_DEFINED
|
||||||
UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
SLONG new_length,
|
ULONG new_length,
|
||||||
bool flag)
|
bool flag)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -3686,7 +3674,7 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
|||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
if (SetFilePointer(shmem_data->sh_mem_handle, new_length, NULL, FILE_BEGIN) == 0xFFFFFFFF ||
|
if (SetFilePointer(shmem_data->sh_mem_handle, new_length, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
|
||||||
!SetEndOfFile(shmem_data->sh_mem_handle) ||
|
!SetEndOfFile(shmem_data->sh_mem_handle) ||
|
||||||
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
|
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
|
||||||
{
|
{
|
||||||
@ -3709,16 +3697,15 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
|||||||
HANDLE file_obj;
|
HANDLE file_obj;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
TEXT expanded_filename[MAXPATHLEN];
|
TEXT mapping_name[MAXPATHLEN + 15]; // enough for int32 as text
|
||||||
sprintf(expanded_filename, "%s%"SLONGFORMAT, shmem_data->sh_mem_name,
|
sprintf(mapping_name, "%s_mapping_%"ULONGFORMAT,
|
||||||
shmem_data->sh_mem_hdr_address[1] + 1);
|
shmem_data->sh_mem_name, shmem_data->sh_mem_hdr_address[1] + 1);
|
||||||
|
|
||||||
file_obj = CreateFileMapping(shmem_data->sh_mem_handle,
|
file_obj = CreateFileMapping(shmem_data->sh_mem_handle,
|
||||||
ISC_get_security_desc(),
|
ISC_get_security_desc(),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
0,
|
0, new_length,
|
||||||
new_length,
|
mapping_name);
|
||||||
expanded_filename);
|
|
||||||
|
|
||||||
if (!((GetLastError() == ERROR_ALREADY_EXISTS) && flag))
|
if (!((GetLastError() == ERROR_ALREADY_EXISTS) && flag))
|
||||||
break;
|
break;
|
||||||
@ -3766,7 +3753,7 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
|||||||
#ifndef ISC_REMAP_FILE_DEFINED
|
#ifndef ISC_REMAP_FILE_DEFINED
|
||||||
UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
|
||||||
SH_MEM shmem_data,
|
SH_MEM shmem_data,
|
||||||
SLONG new_length,
|
ULONG new_length,
|
||||||
bool flag)
|
bool flag)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -861,9 +861,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
|
|
||||||
bool first = false;
|
bool first = false;
|
||||||
|
|
||||||
LCK_init(tdbb, LCK_OWNER_attachment); // For the attachment
|
|
||||||
attachment->att_flags |= ATT_lck_init_done;
|
|
||||||
|
|
||||||
if (dbb->dbb_filename.empty())
|
if (dbb->dbb_filename.empty())
|
||||||
{
|
{
|
||||||
#if defined(DEV_BUILD) && defined(SUPERSERVER)
|
#if defined(DEV_BUILD) && defined(SUPERSERVER)
|
||||||
@ -891,19 +888,22 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
else
|
else
|
||||||
dbb->dbb_database_name = expanded_name;
|
dbb->dbb_database_name = expanded_name;
|
||||||
|
|
||||||
// Extra LCK_init() done to keep the lock table until the
|
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
// database is shutdown() after the last detach.
|
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
|
||||||
|
|
||||||
|
// Initialize the lock manager
|
||||||
|
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
|
||||||
|
|
||||||
LCK_init(tdbb, LCK_OWNER_database);
|
LCK_init(tdbb, LCK_OWNER_database);
|
||||||
dbb->dbb_flags |= DBB_lck_init_done;
|
dbb->dbb_flags |= DBB_lck_init_done;
|
||||||
|
|
||||||
INI_init(tdbb);
|
LCK_init(tdbb, LCK_OWNER_attachment);
|
||||||
|
attachment->att_flags |= ATT_lck_init_done;
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
|
||||||
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
|
|
||||||
|
|
||||||
// Initialize locks
|
// Initialize locks
|
||||||
init_database_locks(tdbb);
|
init_database_locks(tdbb);
|
||||||
|
|
||||||
|
INI_init(tdbb);
|
||||||
SHUT_init(tdbb);
|
SHUT_init(tdbb);
|
||||||
PAG_header_init(tdbb);
|
PAG_header_init(tdbb);
|
||||||
INI_init2(tdbb);
|
INI_init2(tdbb);
|
||||||
@ -939,6 +939,11 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
|||||||
// looks like someone tries to attach incompatibly
|
// looks like someone tries to attach incompatibly
|
||||||
status_exception::raise(Arg::Gds(isc_bad_dpb_content));
|
status_exception::raise(Arg::Gds(isc_bad_dpb_content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_assert(dbb->dbb_lock_mgr);
|
||||||
|
|
||||||
|
LCK_init(tdbb, LCK_OWNER_attachment);
|
||||||
|
attachment->att_flags |= ATT_lck_init_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachments to a ReadOnly database need NOT do garbage collection
|
// Attachments to a ReadOnly database need NOT do garbage collection
|
||||||
@ -1361,9 +1366,7 @@ ISC_STATUS GDS_CANCEL_BLOB(ISC_STATUS* user_status, blb** blob_handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS* user_status,
|
ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS* user_status, Attachment** handle, SLONG* id)
|
||||||
Attachment** handle,
|
|
||||||
SLONG* id)
|
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1383,7 +1386,12 @@ ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS* user_status,
|
|||||||
DatabaseContextHolder dbbHolder(tdbb);
|
DatabaseContextHolder dbbHolder(tdbb);
|
||||||
check_database(tdbb);
|
check_database(tdbb);
|
||||||
|
|
||||||
EVENT_cancel(*id);
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
|
if (dbb->dbb_event_mgr)
|
||||||
|
{
|
||||||
|
dbb->dbb_event_mgr->cancelEvents(*id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const Exception& ex)
|
catch (const Exception& ex)
|
||||||
{
|
{
|
||||||
@ -1823,19 +1831,6 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
|
|
||||||
dbb->dbb_page_size = (page_size > MAX_PAGE_SIZE) ? MAX_PAGE_SIZE : page_size;
|
dbb->dbb_page_size = (page_size > MAX_PAGE_SIZE) ? MAX_PAGE_SIZE : page_size;
|
||||||
|
|
||||||
LCK_init(tdbb, LCK_OWNER_attachment); // For the attachment
|
|
||||||
attachment->att_flags |= ATT_lck_init_done;
|
|
||||||
// Extra LCK_init() done to keep the lock table until the
|
|
||||||
// database is shutdown() after the last detach.
|
|
||||||
LCK_init(tdbb, LCK_OWNER_database);
|
|
||||||
dbb->dbb_flags |= DBB_lck_init_done;
|
|
||||||
|
|
||||||
INI_init(tdbb);
|
|
||||||
PAG_init(tdbb);
|
|
||||||
initing_security = true;
|
|
||||||
|
|
||||||
SCL_init(tdbb, true, userId);
|
|
||||||
|
|
||||||
initing_security = false;
|
initing_security = false;
|
||||||
|
|
||||||
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
|
||||||
@ -1885,9 +1880,24 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
|||||||
|
|
||||||
const jrd_file* const first_dbb_file = pageSpace->file;
|
const jrd_file* const first_dbb_file = pageSpace->file;
|
||||||
|
|
||||||
|
// Initialize the lock manager
|
||||||
|
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
|
||||||
|
|
||||||
|
LCK_init(tdbb, LCK_OWNER_database);
|
||||||
|
dbb->dbb_flags |= DBB_lck_init_done;
|
||||||
|
|
||||||
|
LCK_init(tdbb, LCK_OWNER_attachment);
|
||||||
|
attachment->att_flags |= ATT_lck_init_done;
|
||||||
|
|
||||||
// Initialize locks
|
// Initialize locks
|
||||||
init_database_locks(tdbb);
|
init_database_locks(tdbb);
|
||||||
|
|
||||||
|
INI_init(tdbb);
|
||||||
|
PAG_init(tdbb);
|
||||||
|
initing_security = true;
|
||||||
|
|
||||||
|
SCL_init(tdbb, true, userId);
|
||||||
|
|
||||||
if (options.dpb_set_page_buffers)
|
if (options.dpb_set_page_buffers)
|
||||||
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
||||||
|
|
||||||
@ -2524,13 +2534,17 @@ ISC_STATUS GDS_QUE_EVENTS(ISC_STATUS* user_status,
|
|||||||
Database* const dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
Lock* const lock = dbb->dbb_lock;
|
Lock* const lock = dbb->dbb_lock;
|
||||||
|
|
||||||
|
EventManager::init(dbb);
|
||||||
|
|
||||||
if (!attachment->att_event_session)
|
if (!attachment->att_event_session)
|
||||||
{
|
{
|
||||||
attachment->att_event_session = EVENT_create_session();
|
attachment->att_event_session = dbb->dbb_event_mgr->createSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
*id = EVENT_que(attachment->att_event_session, lock->lck_length,
|
*id = dbb->dbb_event_mgr->queEvents(attachment->att_event_session,
|
||||||
(const TEXT*) &lock->lck_key, length, items, ast, arg);
|
lock->lck_length, (const TEXT*) &lock->lck_key,
|
||||||
|
length, items,
|
||||||
|
ast, arg);
|
||||||
}
|
}
|
||||||
catch (const Exception& ex)
|
catch (const Exception& ex)
|
||||||
{
|
{
|
||||||
@ -4654,10 +4668,6 @@ static Database* init(thread_db* tdbb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the lock manager
|
|
||||||
|
|
||||||
dbb->dbb_lock_mgr = LockManager::create(expanded_filename);
|
|
||||||
|
|
||||||
// Initialize a number of subsystems
|
// Initialize a number of subsystems
|
||||||
|
|
||||||
TRA_init(dbb);
|
TRA_init(dbb);
|
||||||
@ -4672,8 +4682,6 @@ static Database* init(thread_db* tdbb,
|
|||||||
dbb->dbb_decrypt = (Database::crypt_routine) crypt_lib.lookupSymbol(decrypt_entrypoint);
|
dbb->dbb_decrypt = (Database::crypt_routine) crypt_lib.lookupSymbol(decrypt_entrypoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTL_init(tdbb);
|
|
||||||
|
|
||||||
return dbb;
|
return dbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4838,8 +4846,10 @@ static void release_attachment(thread_db* tdbb, Attachment* attachment, ISC_STAT
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (attachment->att_event_session)
|
if (dbb->dbb_event_mgr && attachment->att_event_session)
|
||||||
EVENT_delete_session(attachment->att_event_session);
|
{
|
||||||
|
dbb->dbb_event_mgr->deleteSession(attachment->att_event_session);
|
||||||
|
}
|
||||||
|
|
||||||
if (attachment->att_id_lock)
|
if (attachment->att_id_lock)
|
||||||
LCK_release(tdbb, attachment->att_id_lock);
|
LCK_release(tdbb, attachment->att_id_lock);
|
||||||
@ -4870,7 +4880,7 @@ static void release_attachment(thread_db* tdbb, Attachment* attachment, ISC_STAT
|
|||||||
detachLocksFromAttachment(attachment);
|
detachLocksFromAttachment(attachment);
|
||||||
|
|
||||||
if (attachment->att_flags & ATT_lck_init_done) {
|
if (attachment->att_flags & ATT_lck_init_done) {
|
||||||
LCK_fini(tdbb, LCK_OWNER_attachment); // For the attachment
|
LCK_fini(tdbb, LCK_OWNER_attachment);
|
||||||
attachment->att_flags &= ~ATT_lck_init_done;
|
attachment->att_flags &= ~ATT_lck_init_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5088,8 +5098,6 @@ static void shutdown_database(Database* dbb, const bool release_pools)
|
|||||||
CMP_fini(tdbb);
|
CMP_fini(tdbb);
|
||||||
CCH_fini(tdbb);
|
CCH_fini(tdbb);
|
||||||
|
|
||||||
DatabaseSnapshot::cleanup(tdbb);
|
|
||||||
|
|
||||||
if (dbb->dbb_backup_manager)
|
if (dbb->dbb_backup_manager)
|
||||||
dbb->dbb_backup_manager->shutdown(tdbb);
|
dbb->dbb_backup_manager->shutdown(tdbb);
|
||||||
|
|
||||||
@ -5150,7 +5158,7 @@ static void shutdown_database(Database* dbb, const bool release_pools)
|
|||||||
if (dbb->dbb_flags & DBB_lck_init_done) {
|
if (dbb->dbb_flags & DBB_lck_init_done) {
|
||||||
dbb->dbb_page_manager.releaseLocks();
|
dbb->dbb_page_manager.releaseLocks();
|
||||||
|
|
||||||
LCK_fini(tdbb, LCK_OWNER_database); // For the database
|
LCK_fini(tdbb, LCK_OWNER_database);
|
||||||
dbb->dbb_flags &= ~DBB_lck_init_done;
|
dbb->dbb_flags &= ~DBB_lck_init_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "../common/classes/alloc.h"
|
#include "../common/classes/alloc.h"
|
||||||
#include "../common/classes/init.h"
|
#include "../common/classes/init.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
|
#include "../jrd/ThreadStart.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "../include/fb_blk.h"
|
#include "../include/fb_blk.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
|
#include "../jrd/ods.h"
|
||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
#include <process.h>
|
#include <process.h>
|
||||||
#define MUTEX &m_shmemMutex
|
#define MUTEX &m_shmemMutex
|
||||||
#else
|
#else
|
||||||
#define MUTEX m_header->lhb_mutex
|
#define MUTEX &m_header->lhb_mutex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
@ -159,17 +159,12 @@ static const bool compatibility[LCK_max][LCK_max] =
|
|||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
const char* LockManager::PATTERN = "firebird_db_%d_lock";
|
|
||||||
|
|
||||||
Firebird::GlobalPtr<LockManager::DbLockMgrMap> LockManager::g_lmMap;
|
Firebird::GlobalPtr<LockManager::DbLockMgrMap> LockManager::g_lmMap;
|
||||||
Firebird::GlobalPtr<Firebird::Mutex> LockManager::g_mapMutex;
|
Firebird::GlobalPtr<Firebird::Mutex> LockManager::g_mapMutex;
|
||||||
|
|
||||||
|
|
||||||
LockManager* LockManager::create(const Firebird::PathName& filename)
|
LockManager* LockManager::create(const Firebird::string& id)
|
||||||
{
|
{
|
||||||
//const size_t HASH_SIZE = 997;
|
|
||||||
const int id = 0;//filename.hash(HASH_SIZE);
|
|
||||||
|
|
||||||
Firebird::MutexLockGuard guard(g_mapMutex);
|
Firebird::MutexLockGuard guard(g_mapMutex);
|
||||||
|
|
||||||
LockManager* lockMgr = NULL;
|
LockManager* lockMgr = NULL;
|
||||||
@ -180,26 +175,24 @@ LockManager* LockManager::create(const Firebird::PathName& filename)
|
|||||||
|
|
||||||
fb_assert(lockMgr);
|
fb_assert(lockMgr);
|
||||||
|
|
||||||
lockMgr->addRef();
|
|
||||||
return lockMgr;
|
return lockMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockManager::LockManager(int dbId)
|
|
||||||
|
LockManager::LockManager(const Firebird::string& id)
|
||||||
: PID(getpid()),
|
: PID(getpid()),
|
||||||
m_bugcheck(false),
|
m_bugcheck(false),
|
||||||
m_header(NULL),
|
m_header(NULL),
|
||||||
m_process(NULL),
|
m_process(NULL),
|
||||||
m_processOffset(0),
|
m_processOffset(0),
|
||||||
m_dbId(dbId),
|
m_dbId(getPool(), id)
|
||||||
m_lockFile(getPool())
|
|
||||||
{
|
{
|
||||||
// m_lockFile.printf(PATTERN, m_dbId);
|
Firebird::string name;
|
||||||
TEXT buffer[MAXPATHLEN];
|
name.printf(LOCK_FILE, m_dbId.c_str());
|
||||||
gds__prefix_lock(buffer, LOCK_FILE);
|
|
||||||
m_lockFile = buffer;
|
|
||||||
|
|
||||||
ISC_STATUS_ARRAY local_status;
|
ISC_STATUS_ARRAY local_status;
|
||||||
if (!(m_header = (lhb*) ISC_map_file(local_status, m_lockFile.c_str(),
|
if (!(m_header = (lhb*) ISC_map_file(local_status,
|
||||||
|
name.c_str(),
|
||||||
initialize, this,
|
initialize, this,
|
||||||
Config::getLockMemSize(),
|
Config::getLockMemSize(),
|
||||||
&m_shmem)))
|
&m_shmem)))
|
||||||
@ -207,6 +200,8 @@ LockManager::LockManager(int dbId)
|
|||||||
Firebird::status_exception::raise(local_status);
|
Firebird::status_exception::raise(local_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_assert(m_header->lhb_version == LHB_VERSION);
|
||||||
|
|
||||||
Firebird::MutexLockGuard guard(g_mapMutex);
|
Firebird::MutexLockGuard guard(g_mapMutex);
|
||||||
|
|
||||||
if (g_lmMap->put(m_dbId, this))
|
if (g_lmMap->put(m_dbId, this))
|
||||||
@ -251,10 +246,9 @@ LockManager::~LockManager()
|
|||||||
release_mutex();
|
release_mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
ISC_mutex_fini(MUTEX);
|
|
||||||
|
|
||||||
if (m_header)
|
if (m_header)
|
||||||
{
|
{
|
||||||
|
ISC_mutex_fini(MUTEX);
|
||||||
ISC_unmap_file(local_status, &m_shmem);
|
ISC_unmap_file(local_status, &m_shmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +501,7 @@ SRQ_PTR LockManager::enqueue(thread_db* tdbb,
|
|||||||
else {
|
else {
|
||||||
++m_header->lhb_operations[0];
|
++m_header->lhb_operations[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_tail(&lock->lbl_requests, &request->lrq_lbl_requests);
|
insert_tail(&lock->lbl_requests, &request->lrq_lbl_requests);
|
||||||
request->lrq_data = data;
|
request->lrq_data = data;
|
||||||
const SRQ_PTR lock_id = grant_or_que(tdbb, request, lock, lck_wait);
|
const SRQ_PTR lock_id = grant_or_que(tdbb, request, lock, lck_wait);
|
||||||
@ -1062,7 +1056,7 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const SLONG length = m_header->lhb_length;
|
const ULONG new_length = m_header->lhb_length;
|
||||||
|
|
||||||
#if (defined HAVE_MMAP || defined WIN_NT)
|
#if (defined HAVE_MMAP || defined WIN_NT)
|
||||||
Firebird::WriteLockGuard guard(m_remapSync);
|
Firebird::WriteLockGuard guard(m_remapSync);
|
||||||
@ -1070,7 +1064,7 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
|
|||||||
remap_local_owners();
|
remap_local_owners();
|
||||||
// Remap the shared memory region
|
// Remap the shared memory region
|
||||||
ISC_STATUS_ARRAY status_vector;
|
ISC_STATUS_ARRAY status_vector;
|
||||||
lhb* const header = (lhb*) ISC_remap_file(status_vector, &m_shmem, length, false);
|
lhb* const header = (lhb*) ISC_remap_file(status_vector, &m_shmem, new_length, false);
|
||||||
if (header)
|
if (header)
|
||||||
m_header = header;
|
m_header = header;
|
||||||
else
|
else
|
||||||
@ -1109,7 +1103,7 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UCHAR* LockManager::alloc(SSHORT size, ISC_STATUS* status_vector)
|
UCHAR* LockManager::alloc(USHORT size, ISC_STATUS* status_vector)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1124,32 +1118,22 @@ UCHAR* LockManager::alloc(SSHORT size, ISC_STATUS* status_vector)
|
|||||||
size = FB_ALIGN(size, FB_ALIGNMENT);
|
size = FB_ALIGN(size, FB_ALIGNMENT);
|
||||||
ASSERT_ACQUIRED;
|
ASSERT_ACQUIRED;
|
||||||
const ULONG block = m_header->lhb_used;
|
const ULONG block = m_header->lhb_used;
|
||||||
m_header->lhb_used += size;
|
|
||||||
|
|
||||||
// Make sure we haven't overflowed the lock table. If so, bump the size of the table.
|
// Make sure we haven't overflowed the lock table. If so, bump the size of the table.
|
||||||
|
|
||||||
if (m_header->lhb_used > m_header->lhb_length
|
if (m_header->lhb_used + size > m_header->lhb_length)
|
||||||
#ifdef LOCK_DEBUG_REMAP
|
|
||||||
// If we're debugging remaps, force a remap every-so-often.
|
|
||||||
|| ((debug_remap_count++ % DEBUG_REMAP_INTERVAL) == 0 && m_processOffset)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const bool extend = (m_header->lhb_used > m_header->lhb_length);
|
|
||||||
m_header->lhb_used -= size;
|
|
||||||
|
|
||||||
#if (defined HAVE_MMAP || defined WIN_NT)
|
#if (defined HAVE_MMAP || defined WIN_NT)
|
||||||
Firebird::WriteLockGuard guard(m_remapSync);
|
Firebird::WriteLockGuard guard(m_remapSync);
|
||||||
// Post remapping notifications
|
// Post remapping notifications
|
||||||
remap_local_owners();
|
remap_local_owners();
|
||||||
// Remap the shared memory region
|
// Remap the shared memory region
|
||||||
const ULONG length = m_shmem.sh_mem_length_mapped + (extend ? Config::getLockMemSize() : 0);
|
const ULONG new_length = m_shmem.sh_mem_length_mapped + Config::getLockMemSize();
|
||||||
lhb* header = (lhb*) ISC_remap_file(status_vector, &m_shmem, length, true);
|
lhb* header = (lhb*) ISC_remap_file(status_vector, &m_shmem, new_length, true);
|
||||||
if (header) {
|
if (header) {
|
||||||
m_header = header;
|
m_header = header;
|
||||||
ASSERT_ACQUIRED;
|
ASSERT_ACQUIRED;
|
||||||
m_header->lhb_length = m_shmem.sh_mem_length_mapped;
|
m_header->lhb_length = m_shmem.sh_mem_length_mapped;
|
||||||
m_header->lhb_used += size;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -1169,6 +1153,8 @@ UCHAR* LockManager::alloc(SSHORT size, ISC_STATUS* status_vector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_header->lhb_used += size;
|
||||||
|
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
// This version of alloc() doesn't initialize memory. To shake out
|
// This version of alloc() doesn't initialize memory. To shake out
|
||||||
// any bugs, in DEV_BUILD we initialize it to a "funny" pattern.
|
// any bugs, in DEV_BUILD we initialize it to a "funny" pattern.
|
||||||
@ -1299,14 +1285,6 @@ void LockManager::blocking_action(thread_db* tdbb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
THREAD_ENTRY_DECLARE LockManager::blocking_action_thread(THREAD_ENTRY_PARAM arg)
|
|
||||||
{
|
|
||||||
LockManager* const lockMgr = static_cast<LockManager*>(arg);
|
|
||||||
lockMgr->blocking_action_thread();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LockManager::blocking_action_thread()
|
void LockManager::blocking_action_thread()
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
@ -1334,14 +1312,12 @@ void LockManager::blocking_action_thread()
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SRQ_PTR* process_offset_ptr = (SRQ_PTR*) &m_processOffset;
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
m_localMutex.enter();
|
m_localMutex.enter();
|
||||||
|
|
||||||
// See if the main thread has requested us to go away
|
// See if the main thread has requested us to go away
|
||||||
if (!*process_offset_ptr || m_process->prc_process_id != PID)
|
if (!m_processOffset || m_process->prc_process_id != PID)
|
||||||
{
|
{
|
||||||
if (atStartup)
|
if (atStartup)
|
||||||
{
|
{
|
||||||
@ -1357,7 +1333,7 @@ void LockManager::blocking_action_thread()
|
|||||||
Firebird::HalfStaticArray<SRQ_PTR, 4> blocking_owners;
|
Firebird::HalfStaticArray<SRQ_PTR, 4> blocking_owners;
|
||||||
|
|
||||||
acquire_shmem(DUMMY_OWNER);
|
acquire_shmem(DUMMY_OWNER);
|
||||||
const prc* const process = (prc*) SRQ_ABS_PTR(*process_offset_ptr);
|
const prc* const process = (prc*) SRQ_ABS_PTR(m_processOffset);
|
||||||
|
|
||||||
srq* lock_srq;
|
srq* lock_srq;
|
||||||
SRQ_LOOP(process->prc_owners, lock_srq)
|
SRQ_LOOP(process->prc_owners, lock_srq)
|
||||||
@ -1368,7 +1344,7 @@ void LockManager::blocking_action_thread()
|
|||||||
|
|
||||||
release_mutex();
|
release_mutex();
|
||||||
|
|
||||||
while (blocking_owners.getCount() && *process_offset_ptr)
|
while (blocking_owners.getCount() && m_processOffset)
|
||||||
{
|
{
|
||||||
const SRQ_PTR owner_offset = blocking_owners.pop();
|
const SRQ_PTR owner_offset = blocking_owners.pop();
|
||||||
acquire_shmem(owner_offset);
|
acquire_shmem(owner_offset);
|
||||||
@ -1466,6 +1442,18 @@ void LockManager::bug(ISC_STATUS* status_vector, const TEXT* string)
|
|||||||
{
|
{
|
||||||
m_bugcheck = true;
|
m_bugcheck = true;
|
||||||
|
|
||||||
|
// The lock table has some problem - copy it for later analysis
|
||||||
|
|
||||||
|
TEXT buffer[MAXPATHLEN];
|
||||||
|
gds__prefix(buffer, "lock_table.dump");
|
||||||
|
const TEXT* const lock_file = buffer;
|
||||||
|
FILE* const fd = fopen(lock_file, "wb");
|
||||||
|
if (fd)
|
||||||
|
{
|
||||||
|
fwrite(m_header, 1, m_header->lhb_used, fd);
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
// If the current mutex acquirer is in the same process, release the mutex
|
// If the current mutex acquirer is in the same process, release the mutex
|
||||||
|
|
||||||
if (m_header && (m_header->lhb_active_owner > 0)) {
|
if (m_header && (m_header->lhb_active_owner > 0)) {
|
||||||
@ -1519,8 +1507,7 @@ bool LockManager::create_owner(ISC_STATUS* status_vector,
|
|||||||
if (m_header->lhb_version != LHB_VERSION)
|
if (m_header->lhb_version != LHB_VERSION)
|
||||||
{
|
{
|
||||||
TEXT bug_buffer[BUFFER_TINY];
|
TEXT bug_buffer[BUFFER_TINY];
|
||||||
sprintf(bug_buffer,
|
sprintf(bug_buffer, "inconsistent lock table version number; found %d, expected %d",
|
||||||
"inconsistent lock table version number; found %d, expected %d",
|
|
||||||
m_header->lhb_version, LHB_VERSION);
|
m_header->lhb_version, LHB_VERSION);
|
||||||
bug(status_vector, bug_buffer);
|
bug(status_vector, bug_buffer);
|
||||||
return false;
|
return false;
|
||||||
@ -2152,6 +2139,7 @@ void LockManager::init_owner_block(own* owner, UCHAR owner_type, LOCK_OWNER_T ow
|
|||||||
owner->own_count = 1;
|
owner->own_count = 1;
|
||||||
owner->own_owner_id = owner_id;
|
owner->own_owner_id = owner_id;
|
||||||
owner->own_process = m_processOffset;
|
owner->own_process = m_processOffset;
|
||||||
|
owner->own_thread_id = 0;
|
||||||
SRQ_INIT(owner->own_lhb_owners);
|
SRQ_INIT(owner->own_lhb_owners);
|
||||||
SRQ_INIT(owner->own_prc_owners);
|
SRQ_INIT(owner->own_prc_owners);
|
||||||
SRQ_INIT(owner->own_requests);
|
SRQ_INIT(owner->own_requests);
|
||||||
@ -2177,7 +2165,7 @@ void LockManager::initialize(SH_MEM shmem_data, bool initialize)
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
if (ISC_mutex_init(MUTEX, m_lockFile.c_str())) {
|
if (ISC_mutex_init(MUTEX, shmem_data->sh_mem_name)) {
|
||||||
bug(NULL, "mutex init failed");
|
bug(NULL, "mutex init failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2236,7 +2224,7 @@ void LockManager::initialize(SH_MEM shmem_data, bool initialize)
|
|||||||
if (Config::getLockGrantOrder())
|
if (Config::getLockGrantOrder())
|
||||||
m_header->lhb_flags |= LHB_lock_ordering;
|
m_header->lhb_flags |= LHB_lock_ordering;
|
||||||
|
|
||||||
const SLONG length = sizeof(lhb) + (m_header->lhb_hash_slots * sizeof(m_header->lhb_hash[0]));
|
const ULONG length = sizeof(lhb) + (m_header->lhb_hash_slots * sizeof(m_header->lhb_hash[0]));
|
||||||
m_header->lhb_length = shmem_data->sh_mem_length_mapped;
|
m_header->lhb_length = shmem_data->sh_mem_length_mapped;
|
||||||
m_header->lhb_used = FB_ALIGN(length, FB_ALIGNMENT);
|
m_header->lhb_used = FB_ALIGN(length, FB_ALIGNMENT);
|
||||||
|
|
||||||
|
@ -90,14 +90,12 @@ const SSHORT LCK_NO_WAIT = 0;
|
|||||||
|
|
||||||
const UCHAR type_null = 0;
|
const UCHAR type_null = 0;
|
||||||
const UCHAR type_lhb = 1;
|
const UCHAR type_lhb = 1;
|
||||||
const UCHAR type_prb = 2;
|
const UCHAR type_lrq = 2;
|
||||||
const UCHAR type_lrq = 3;
|
const UCHAR type_lbl = 3;
|
||||||
const UCHAR type_lbl = 4;
|
const UCHAR type_his = 4;
|
||||||
const UCHAR type_his = 5;
|
const UCHAR type_shb = 5;
|
||||||
const UCHAR type_smbx = 6;
|
const UCHAR type_own = 6;
|
||||||
const UCHAR type_shb = 7;
|
const UCHAR type_lpr = 7;
|
||||||
const UCHAR type_own = 8;
|
|
||||||
const UCHAR type_lpr = 9;
|
|
||||||
const UCHAR type_MAX = type_lpr;
|
const UCHAR type_MAX = type_lpr;
|
||||||
|
|
||||||
// Version number of the lock table.
|
// Version number of the lock table.
|
||||||
@ -134,11 +132,11 @@ struct lhb
|
|||||||
srq lhb_free_owners; // Free owner blocks
|
srq lhb_free_owners; // Free owner blocks
|
||||||
srq lhb_free_locks; // Free lock blocks
|
srq lhb_free_locks; // Free lock blocks
|
||||||
srq lhb_free_requests; // Free lock requests
|
srq lhb_free_requests; // Free lock requests
|
||||||
SLONG lhb_length; // Size of lock table
|
ULONG lhb_length; // Size of lock table
|
||||||
SLONG lhb_used; // Bytes of lock table in use
|
ULONG lhb_used; // Bytes of lock table in use
|
||||||
USHORT lhb_hash_slots; // Number of hash slots allocated
|
USHORT lhb_hash_slots; // Number of hash slots allocated
|
||||||
USHORT lhb_flags; // Miscellaneous info
|
USHORT lhb_flags; // Miscellaneous info
|
||||||
mtx lhb_mutex[1]; // Mutex controlling access
|
struct mtx lhb_mutex; // Mutex controlling access
|
||||||
SRQ_PTR lhb_history;
|
SRQ_PTR lhb_history;
|
||||||
ULONG lhb_scan_interval; // Deadlock scan interval (secs)
|
ULONG lhb_scan_interval; // Deadlock scan interval (secs)
|
||||||
ULONG lhb_acquire_spins;
|
ULONG lhb_acquire_spins;
|
||||||
|
@ -43,16 +43,15 @@ class thread_db;
|
|||||||
|
|
||||||
class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
|
class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||||
{
|
{
|
||||||
typedef Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<int, LockManager*> > > DbLockMgrMap;
|
typedef Firebird::GenericMap<Firebird::Pair<Firebird::Left<Firebird::string, LockManager*> > > DbLockMgrMap;
|
||||||
|
|
||||||
static Firebird::GlobalPtr<DbLockMgrMap> g_lmMap;
|
static Firebird::GlobalPtr<DbLockMgrMap> g_lmMap;
|
||||||
static Firebird::GlobalPtr<Firebird::Mutex> g_mapMutex;
|
static Firebird::GlobalPtr<Firebird::Mutex> g_mapMutex;
|
||||||
static const char* PATTERN;
|
|
||||||
|
|
||||||
const int PID;
|
const int PID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static LockManager* create(const Firebird::PathName&);
|
static LockManager* create(const Firebird::string&);
|
||||||
|
|
||||||
bool initializeOwner(thread_db*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
|
bool initializeOwner(thread_db*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
|
||||||
void shutdownOwner(thread_db*, SRQ_PTR*);
|
void shutdownOwner(thread_db*, SRQ_PTR*);
|
||||||
@ -72,7 +71,7 @@ public:
|
|||||||
SLONG writeData(SRQ_PTR, SLONG);
|
SLONG writeData(SRQ_PTR, SLONG);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit LockManager(int);
|
explicit LockManager(const Firebird::string&);
|
||||||
~LockManager();
|
~LockManager();
|
||||||
|
|
||||||
bool lockOrdering() const
|
bool lockOrdering() const
|
||||||
@ -81,7 +80,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void acquire_shmem(SRQ_PTR);
|
void acquire_shmem(SRQ_PTR);
|
||||||
UCHAR* alloc(SSHORT, ISC_STATUS*);
|
UCHAR* alloc(USHORT, ISC_STATUS*);
|
||||||
lbl* alloc_lock(USHORT, ISC_STATUS*);
|
lbl* alloc_lock(USHORT, ISC_STATUS*);
|
||||||
void blocking_action(thread_db*, SRQ_PTR, SRQ_PTR);
|
void blocking_action(thread_db*, SRQ_PTR, SRQ_PTR);
|
||||||
void blocking_action_thread();
|
void blocking_action_thread();
|
||||||
@ -133,7 +132,12 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
USHORT wait_for_request(thread_db*, lrq*, SSHORT);
|
USHORT wait_for_request(thread_db*, lrq*, SSHORT);
|
||||||
|
|
||||||
static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM);
|
static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM arg)
|
||||||
|
{
|
||||||
|
LockManager* const lockMgr = static_cast<LockManager*>(arg);
|
||||||
|
lockMgr->blocking_action_thread();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void initialize(void* arg, SH_MEM shmem, bool init)
|
static void initialize(void* arg, SH_MEM shmem, bool init)
|
||||||
{
|
{
|
||||||
@ -155,8 +159,7 @@ private:
|
|||||||
Firebird::Semaphore m_cleanupSemaphore;
|
Firebird::Semaphore m_cleanupSemaphore;
|
||||||
Firebird::Semaphore m_startupSemaphore;
|
Firebird::Semaphore m_startupSemaphore;
|
||||||
|
|
||||||
const int m_dbId;
|
Firebird::string m_dbId;
|
||||||
Firebird::PathName m_lockFile;
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
struct mtx m_shmemMutex;
|
struct mtx m_shmemMutex;
|
||||||
|
@ -67,6 +67,8 @@ const char* INTERBASE_USER = "interbase";
|
|||||||
const char* FIREBIRD_USER = "firebird";
|
const char* FIREBIRD_USER = "firebird";
|
||||||
const char* INTERBASE_USER_SHORT= "interbas";
|
const char* INTERBASE_USER_SHORT= "interbas";
|
||||||
|
|
||||||
|
const char* GUARD_FILE = "fb_guard";
|
||||||
|
|
||||||
volatile sig_atomic_t shutting_down;
|
volatile sig_atomic_t shutting_down;
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,11 +256,10 @@ int UTIL_ex_lock(const TEXT* file)
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
|
|
||||||
TEXT expanded_filename[MAXPATHLEN], tmp[MAXPATHLEN], hostname[64];
|
TEXT expanded_filename[MAXPATHLEN];
|
||||||
|
|
||||||
/* get the file name and prepend the complete path etc */
|
/* get the file name and prepend the complete path etc */
|
||||||
gds__prefix_lock(tmp, file);
|
gds__prefix(expanded_filename, file);
|
||||||
sprintf(expanded_filename, tmp, ISC_get_host(hostname, sizeof(hostname)));
|
|
||||||
|
|
||||||
/* file fd for the opened and locked file */
|
/* file fd for the opened and locked file */
|
||||||
int fd_file = open(expanded_filename, O_RDWR | O_CREAT, 0666);
|
int fd_file = open(expanded_filename, O_RDWR | O_CREAT, 0666);
|
||||||
|
Loading…
Reference in New Issue
Block a user