8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 06:43:04 +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:
dimitr 2009-01-28 12:27:18 +00:00
parent bb59a30d0f
commit 1b3927b026
23 changed files with 1040 additions and 1011 deletions

View File

@ -54,6 +54,28 @@ namespace Jrd
#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()
{
delete dbb_sys_trans;
@ -66,9 +88,14 @@ namespace Jrd
MemoryPool::deletePool(dbb_pools[i]);
}
delete dbb_monitoring_data;
dbb_flags |= DBB_destroying;
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)

View File

@ -57,19 +57,20 @@
#include "../common/classes/PublicHandle.h"
#include "../common/classes/semaphore.h"
#include "../common/utils_proto.h"
#include "../jrd/DatabaseSnapshot.h"
#include "../jrd/RandomGenerator.h"
#include "../jrd/os/guid.h"
#include "../jrd/sbm.h"
#include "../jrd/flu.h"
#include "../jrd/RuntimeStatistics.h"
#include "../lock/lock_proto.h"
#include "../jrd/os/thd_priority.h"
#include "../jrd/event_proto.h"
#include "../lock/lock_proto.h"
class CharSetContainer;
namespace Jrd
{
class Trigger;
template <typename T> class vec;
class jrd_prc;
@ -326,10 +327,10 @@ public:
return TypedHandle<type_dbb>::checkHandle();
}
mutable Sync* dbb_sync; // Database sync primitive
Firebird::Reference dbb_sync_ref; // Database reference to dbb_sync
mutable Firebird::RefPtr<Sync> dbb_sync; // Database sync primitive
LockManager* dbb_lock_mgr;
Firebird::RefPtr<LockManager> dbb_lock_mgr;
Firebird::RefPtr<EventManager> dbb_event_mgr;
Database* dbb_next; // Next database block in system
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_max; // maximum cached value of shared counter lock
jrd_tra* dbb_sys_trans; // system transaction
// jrd_file* dbb_file; // files for I/O operations
Shadow* dbb_shadow; // shadow control block
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_monitor_lock; // lock for monitoring purposes
PageManager dbb_page_manager;
@ -354,6 +353,8 @@ public:
BlobFilter* dbb_blob_filters; // known blob filters
trig_vec* dbb_triggers[DB_TRIGGER_MAX];
DatabaseSnapshot::SharedData* dbb_monitoring_data; // monitoring data
DatabaseModules dbb_modules; // external function/filter modules
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
bool onRawDevice() const;
// returns an unique ID string for a database file
const Firebird::string& getUniqueFileId() const;
MemoryPool* createPool()
{
MemoryPool* const pool = MemoryPool::createPool(dbb_permanent, dbb_memory_stats);
@ -459,7 +463,6 @@ public:
private:
explicit Database(MemoryPool* p)
: dbb_sync(FB_NEW(*getDefaultMemoryPool()) Sync),
dbb_sync_ref(*dbb_sync),
dbb_page_manager(*p),
dbb_modules(*p),
dbb_filename(*p),

View File

@ -72,35 +72,40 @@ const UCHAR TAG_RECORD = MAX_UCHAR;
// SharedMemory class
const ULONG DatabaseSnapshot::SharedMemory::VERSION = 2;
const ULONG DatabaseSnapshot::SharedMemory::DEFAULT_SIZE = 1048576;
DatabaseSnapshot::SharedMemory::SharedMemory()
DatabaseSnapshot::SharedData::SharedData(const Database* dbb)
: process_id(getpid()), local_id(dbb->dbb_monitoring_id)
{
TEXT filename[MAXPATHLEN];
gds__prefix_lock(filename, MONITOR_FILE);
Firebird::string name;
name.printf(MONITOR_FILE, dbb->getUniqueFileId().c_str());
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)
{
iscLogStatus("Cannot initialize the shared memory region", 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_unmap_file(statusVector, &handle);
}
void DatabaseSnapshot::SharedMemory::acquire()
void DatabaseSnapshot::SharedData::acquire()
{
#ifdef WIN_NT
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
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);
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 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;
}
@ -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);
// Remove old copies of our element, if any
doCleanup(dbb);
cleanup();
// Do we need to extend the allocated memory?
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
UCHAR* const ptr = (UCHAR*) base + base->used;
Element* const element = (Element*) ptr;
element->processId = getpid();
element->localId = dbb->dbb_monitoring_id;
element->processId = process_id;
element->localId = local_id;
element->length = length;
memcpy(ptr + sizeof(Element), buffer, 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
doCleanup(dbb);
}
void DatabaseSnapshot::SharedMemory::doCleanup(const Database* const dbb)
{
for (ULONG offset = sizeof(Header); offset < base->used;)
{
UCHAR* const ptr = (UCHAR*) base + offset;
const Element* const element = (Element*) ptr;
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);
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;
@ -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)
{
@ -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);
#ifdef WIN_NT
char buffer[MAXPATHLEN];
gds__prefix_lock(buffer, MONITOR_FILE);
checkMutex("init", ISC_mutex_init(&shmem->mutex, buffer));
checkMutex("init", ISC_mutex_init(&shmem->mutex, shmemData->sh_mem_name));
#endif
if (!initialize)
@ -320,7 +300,7 @@ void DatabaseSnapshot::SharedMemory::init(void* arg, SH_MEM_T* shmemData, bool i
// Initialize the shared data header
Header* const header = (Header*) shmemData->sh_mem_address;
header->version = VERSION;
header->version = MONITOR_VERSION;
header->used = sizeof(Header);
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::SharedMemory* DatabaseSnapshot::dump = NULL;
InitMutex<DatabaseSnapshot> DatabaseSnapshot::startup;
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)
{
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;
// Read the shared memory
fb_assert(dump);
fb_assert(dbb->dbb_monitoring_data);
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);
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);
dump->writeData(tdbb, writer.getBufferLength(), writer.getBuffer());
dbb->dbb_monitoring_data->write(writer.getBufferLength(), writer.getBuffer());
}

View File

@ -30,6 +30,11 @@
namespace Jrd {
// forward declarations
class jrd_rel;
class RecordBuffer;
class RuntimeStatistics;
class DatabaseSnapshot
{
struct RelationData
@ -38,10 +43,18 @@ class DatabaseSnapshot
RecordBuffer* data;
};
class SharedMemory
struct Element
{
static const ULONG VERSION;
static const ULONG DEFAULT_SIZE;
SLONG processId;
SLONG localId;
ULONG length;
};
public:
class SharedData
{
static const ULONG MONITOR_VERSION = 2;
static const ULONG DEFAULT_SIZE = 1048576;
struct Header
{
@ -56,42 +69,40 @@ class DatabaseSnapshot
class DumpGuard
{
public:
explicit DumpGuard(SharedMemory* ptr)
: dump(ptr)
explicit DumpGuard(SharedData* ptr)
: data(ptr)
{
dump->acquire();
data->acquire();
}
~DumpGuard()
{
dump->release();
data->release();
}
private:
DumpGuard(const DumpGuard&);
DumpGuard& operator=(const DumpGuard&);
SharedMemory* dump;
SharedData* const data;
};
public:
SharedMemory();
~SharedMemory();
explicit SharedData(const Database*);
~SharedData();
void acquire();
void release();
UCHAR* readData(thread_db*, MemoryPool&, ULONG&);
void writeData(thread_db*, ULONG, const UCHAR*);
void cleanup(thread_db*);
UCHAR* read(MemoryPool&, ULONG&);
void write(ULONG, const UCHAR*);
private:
// copying is prohibited
SharedMemory(const SharedMemory&);
SharedMemory& operator =(const SharedMemory&);
SharedData(const SharedData&);
SharedData& operator =(const SharedData&);
void doCleanup(const Database* const dbb);
void cleanup();
void extend();
static void checkMutex(const TEXT*, int);
@ -102,29 +113,18 @@ class DatabaseSnapshot
struct mtx mutex;
#endif
Header* base;
const SLONG process_id;
const SLONG local_id;
};
struct Element
{
SLONG processId;
SLONG localId;
ULONG length;
};
public:
~DatabaseSnapshot();
RecordBuffer* getData(const jrd_rel*) const;
static DatabaseSnapshot* create(thread_db*);
static void cleanup(thread_db*);
static int blockingAst(void*);
static void init()
{
dump = FB_NEW(*getDefaultMemoryPool()) SharedMemory;
}
protected:
DatabaseSnapshot(thread_db*, MemoryPool&);
@ -147,9 +147,6 @@ private:
static void putContextVars(Firebird::StringMap&, Firebird::ClumpletWriter&, int, bool);
static void putMemoryUsage(const Firebird::MemoryStats&, Firebird::ClumpletWriter&, int, int);
static SharedMemory* dump;
static Firebird::InitMutex<DatabaseSnapshot> startup;
Firebird::Array<RelationData> snapshot;
Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<SINT64, SLONG> > > idMap;
int idCounter;

View File

@ -634,8 +634,12 @@ void DFW_perform_post_commit_work(jrd_tra* transaction)
switch (work->dfw_type)
{
case dfw_post_event:
EVENT_post(lock->lck_length, (const TEXT*) &lock->lck_key,
work->dfw_name.length(), work->dfw_name.c_str(), work->dfw_count);
EventManager::init(dbb);
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;
delete work;
pending_events = true;
@ -651,7 +655,9 @@ void DFW_perform_post_commit_work(jrd_tra* transaction)
}
if (pending_events)
EVENT_deliver();
{
dbb->dbb_event_mgr->deliverEvents();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,7 @@
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 23-Feb-2002 Dmitry Yemanov - Events wildcarding
*
*
* 2002-02-23 Sean Leyne - Code Cleanup, removed old Win3.1 port (Windows_Only)
*
*/
#ifndef JRD_EVENT_H
@ -36,16 +32,11 @@
// Global section header
const int EVENT_VERSION = 4;
const int EVENT_HASH_SIZE = 7;
const int EVENT_DEFAULT_SIZE = 32768;
const int EVENT_EXTEND_SIZE = 32768;
const int EVENT_VERSION = 4;
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
srq evh_events; // Known events
srq evh_processes; // Known processes
@ -53,11 +44,8 @@ struct evh
SRQ_PTR evh_current_process; // Current process, if any
struct mtx evh_mutex; // Mutex controlling access
SLONG evh_request_id; // Next request id
SRQ_PTR evh_hash_table[EVENT_HASH_SIZE];
};
typedef evh *EVH;
// Common block 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
{
SLONG hdr_length; // Length of block
ULONG hdr_length; // Length of block
UCHAR hdr_type; // Type of block
};
@ -82,7 +70,6 @@ struct frb
event_hdr frb_header;
SLONG frb_next; // Next block
};
typedef frb *FRB;
// Process blocks
@ -95,13 +82,13 @@ struct prb
event_t prb_event; // Event on which to wait
USHORT prb_flags;
};
typedef prb *PRB;
const int PRB_wakeup = 1; // Schedule a wakeup for process
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_over= 8; // remap is over
const int PRB_exiting = 16; // Process is exiting
#endif
// Session block
@ -113,7 +100,6 @@ struct ses
SRQ_PTR ses_interests; // Historical interests
USHORT ses_flags;
};
typedef ses *SES;
const int SES_delivering = 1; // Watcher thread is 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
TEXT evnt_name[1]; // Event name
};
typedef evnt *EVNT;
// Request block
@ -145,7 +130,6 @@ struct evt_req
void *req_ast_arg; // Argument for ast
SLONG req_request_id; // Request id, dummy
};
typedef evt_req *EVT_REQ;
// Request interest block
@ -158,7 +142,6 @@ struct req_int
SRQ_PTR rint_next; // Next interest of request
SLONG rint_count; // Threshold count
};
typedef req_int *RINT;
const int EPB_version1 = 1;

View File

@ -19,21 +19,102 @@
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 23-Feb-2002 Dmitry Yemanov - Events wildcarding
*
*/
#ifndef JRD_EVENT_PROTO_H
#define JRD_EVENT_PROTO_H
void EVENT_cancel(SLONG);
SLONG EVENT_create_session();
void EVENT_delete_session(SLONG);
void EVENT_deliver();
void EVENT_post(USHORT, const TEXT*, USHORT, const TEXT*, USHORT);
SLONG EVENT_que(SLONG, USHORT, const TEXT*, USHORT, const UCHAR*,
FPTR_EVENT_CALLBACK, void*);
#include "../common/classes/init.h"
#include "../common/classes/semaphore.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/RefCounted.h"
#include "../jrd/ThreadData.h"
#include "../jrd/event.h"
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

View File

@ -32,27 +32,13 @@
#ifndef JRD_FILE_PARAMS_H
#define JRD_FILE_PARAMS_H
#ifdef NOHOSTNAME
static const char* EVENT_FILE = "isc_event1";
static const char* LOCK_FILE = "isc_lock1.gbl";
static const char* INIT_FILE = "isc_init1";
static const char* GUARD_FILE = "isc_guard1";
static const char* MONITOR_FILE = "isc_monitor1";
static const char* SEM_FILE = "isc_sem1";
#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";
static const char* EVENT_FILE = "fb_event_%s";
static const char* LOCK_FILE = "fb_lock_%s";
static const char* MONITOR_FILE = "fb_monitor_%s";
#ifdef UNIX
static const char* INIT_FILE = "fb_init";
static const char* SEM_FILE = "fb_sem";
#endif
// CVC: Do we really need this information here after using autoconf?

View File

@ -3648,7 +3648,7 @@ public:
Firebird::PathName lockPrefix;
if (!fb_utils::readenv(FB_LOCK_ENV, lockPrefix))
{
lockPrefix = prefix;
lockPrefix = tempDir;
}
lockPrefix.copyTo(fb_prefix_lock_val, sizeof(fb_prefix_lock_val));
fb_prefix_lock = fb_prefix_lock_val;

View File

@ -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)
{
/**************************************

View File

@ -43,7 +43,6 @@ int INTL_convert_string(dsc*, const dsc*, ErrorFunction);
int INTL_data(const dsc*);
int INTL_data_or_binary(const dsc*);
bool INTL_defined_type(Jrd::thread_db*, USHORT);
void INTL_init(Jrd::thread_db*);
USHORT INTL_key_length(Jrd::thread_db*, USHORT, USHORT);
Jrd::CharSet* INTL_charset_lookup(Jrd::thread_db* tdbb, USHORT parm1);
Jrd::Collation* INTL_texttype_lookup(Jrd::thread_db* tdbb, USHORT parm1);

View File

@ -153,7 +153,7 @@ struct sh_mem
void* sh_mem_object;
void* sh_mem_interest;
void* sh_mem_hdr_object;
SLONG* sh_mem_hdr_address;
ULONG* sh_mem_hdr_address;
TEXT sh_mem_name[MAXPATHLEN];
};
typedef sh_mem SH_MEM_T;

View File

@ -45,7 +45,7 @@ void* ISC_make_signal(bool, bool, int, int);
typedef void (*FPTR_INIT_GLOBAL_REGION)(void*, struct sh_mem*, bool);
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)
int ISC_mutex_init(struct mtx*, const TEXT*);
#else
@ -58,8 +58,8 @@ int ISC_mutex_unlock(struct mtx *);
void ISC_mutex_fini(struct mtx *);
#if defined HAVE_MMAP || defined WIN_NT
UCHAR* ISC_map_object(ISC_STATUS *, SH_MEM, SLONG, SLONG);
void ISC_unmap_object(ISC_STATUS *, SH_MEM, UCHAR **, SLONG);
UCHAR* ISC_map_object(ISC_STATUS *, SH_MEM, ULONG, ULONG);
void ISC_unmap_object(ISC_STATUS *, SH_MEM, UCHAR **, ULONG);
#endif
#ifdef UNIX
@ -72,7 +72,7 @@ void ISC_sync_signals_reset();
ULONG ISC_exception_post(ULONG, const TEXT*);
#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_set_timer(SLONG, FPTR_VOID_PTR, void *, SLONG *, void **);
void ISC_unmap_file(ISC_STATUS *, struct sh_mem *);

View File

@ -131,7 +131,7 @@ union semun
ushort *array;
};
#endif
#endif /* UNIX */
#endif // UNIX
#ifdef HAVE_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,
const TEXT* filename,
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).
*
**************************************/
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
master lock to eliminate possible race conditions with just a single file
locking. The race condition is caused as the conversion of a EXCLUSIVE
lock to a SHARED lock is not atomic*/
TEXT tmp[MAXPATHLEN];
gds__prefix_lock(tmp, INIT_FILE);
string init_filename; /* to hold the complete filename of the init file. */
init_filename.printf(tmp, hostname); /* already have the hostname! */
TEXT init_filename[MAXPATHLEN];
gds__prefix_lock(init_filename, INIT_FILE);
const int oldmask = umask(0);
bool trunc_flag = true;
if (length < 0) {
length = -length;
trunc_flag = false;
}
const bool trunc_flag = (length != 0);
/* open the init lock file */
MutexLockGuard guard(openFdInit);
@ -1931,7 +1928,7 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
#else
int
#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) {
error(status_vector, "open", errno);
return NULL;
@ -1950,10 +1947,9 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
#ifdef USE_SYS5SEMAPHORE
if (fdSem < 0)
{
string semFileName;
gds__prefix_lock(tmp, SEM_FILE);
semFileName.printf(tmp, hostname);
int f = open(semFileName.c_str(), O_RDWR | O_CREAT, 0666);
TEXT sem_filename[MAXPATHLEN];
gds__prefix_lock(sem_filename, SEM_FILE);
int f = open(sem_filename, O_RDWR | O_CREAT, 0666);
if (f == -1) {
error(status_vector, "open", errno);
return NULL;
@ -2098,7 +2094,9 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
const TEXT* filename,
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).
*
**************************************/
//SSHORT count;
TEXT expanded_filename[512];
#ifdef NOHOSTNAME
strcpy(expanded_filename, filename);
#else
TEXT hostname[64];
sprintf(expanded_filename, filename, ISC_get_host(hostname, sizeof(hostname)));
#endif
TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, filename);
const int oldmask = umask(0);
bool init_flag = false;
if (length < 0)
length = -length;
/* Produce shared memory key for file */
@ -2383,13 +2375,12 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
#ifdef WIN_NT
UCHAR* ISC_map_file(
ISC_STATUS* status_vector,
const TEXT* filename,
FPTR_INIT_GLOBAL_REGION init_routine,
void* init_arg,
SLONG length,
SH_MEM shmem_data)
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
const TEXT* filename,
FPTR_INIT_GLOBAL_REGION init_routine,
void* init_arg,
ULONG length,
SH_MEM shmem_data)
{
/**************************************
*
@ -2403,17 +2394,14 @@ UCHAR* ISC_map_file(
* routine (if given) or punt (leaving the file unmapped).
*
**************************************/
TEXT expanded_filename[MAXPATHLEN], hostname[64];
TEXT map_file[MAXPATHLEN];
TEXT object_name[MAXPATHLEN];
HANDLE file_handle, event_handle;
int retry_count = 0;
bool trunc_flag = true;
if (length < 0) {
length = -length;
fb_assert(length > 0); // Was someone so crazy as to pass a bigger value than MAX_SLONG?
trunc_flag = false;
}
TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, filename);
const bool trunc_flag = (length != 0);
/* retry to attach to mmapped file if the process initializing
* dies during initialization.
@ -2422,16 +2410,13 @@ UCHAR* ISC_map_file(
retry:
retry_count++;
ISC_get_host(hostname, sizeof(hostname));
sprintf(map_file, filename, hostname);
file_handle = CreateFile(map_file,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
file_handle = CreateFile(expanded_filename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
error(status_vector, "CreateFile", GetLastError());
return NULL;
@ -2444,14 +2429,14 @@ UCHAR* ISC_map_file(
// Create an event that can be used to determine if someone has already
// 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());
CloseHandle(file_handle);
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) {
error(status_vector, "CreateEvent", GetLastError());
CloseHandle(file_handle);
@ -2512,13 +2497,13 @@ UCHAR* ISC_map_file(
else
fdw_create = OPEN_ALWAYS;
file_handle = CreateFile(map_file,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
fdw_create,
FILE_ATTRIBUTE_NORMAL,
NULL);
file_handle = CreateFile(expanded_filename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
fdw_create,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
CloseHandle(event_handle);
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.
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());
CloseHandle(event_handle);
@ -2536,12 +2521,11 @@ UCHAR* ISC_map_file(
return NULL;
}
HANDLE header_obj = CreateFileMapping ((HANDLE) -1,
ISC_get_security_desc(),
PAGE_READWRITE,
0,
2 * sizeof (SLONG),
expanded_filename);
HANDLE header_obj = CreateFileMapping(INVALID_HANDLE_VALUE,
ISC_get_security_desc(),
PAGE_READWRITE,
0, 2 * sizeof(ULONG),
object_name);
if (header_obj == NULL)
{
error(status_vector, "CreateFileMapping", GetLastError());
@ -2561,7 +2545,7 @@ UCHAR* ISC_map_file(
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) {
error(status_vector, "MapViewOfFile", GetLastError());
@ -2583,16 +2567,14 @@ UCHAR* ISC_map_file(
/* Create the real file mapping object. */
TEXT mapping_filename[sizeof(expanded_filename) + 15]; // enough for int32 as text
sprintf(mapping_filename, "%s%"SLONGFORMAT, expanded_filename, header_address[1]);
TEXT mapping_name[MAXPATHLEN + 15]; // enough for int32 as text
sprintf(mapping_name, "%s_mapping_%"ULONGFORMAT, filename, header_address[1]);
HANDLE file_obj =
CreateFileMapping(file_handle,
ISC_get_security_desc(),
PAGE_READWRITE,
0,
length,
mapping_filename);
HANDLE file_obj = CreateFileMapping(file_handle,
ISC_get_security_desc(),
PAGE_READWRITE,
0, length,
mapping_name);
if (file_obj == NULL) {
error(status_vector, "CreateFileMapping", GetLastError());
UnmapViewOfFile(header_address);
@ -2628,7 +2610,7 @@ UCHAR* ISC_map_file(
shmem_data->sh_mem_interest = event_handle;
shmem_data->sh_mem_hdr_object = header_obj;
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)
(*init_routine) (init_arg, shmem_data, init_flag);
@ -2636,7 +2618,7 @@ UCHAR* ISC_map_file(
if (init_flag) {
FlushViewOfFile(address, 0);
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) ||
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
{
@ -2651,9 +2633,10 @@ UCHAR* ISC_map_file(
#ifdef HAVE_MMAP
UCHAR *ISC_map_object(ISC_STATUS * status_vector,
UCHAR* ISC_map_object(ISC_STATUS* status_vector,
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. */
#ifdef SOLARIS
const SLONG page_size = sysconf(_SC_PAGESIZE);
const ULONG page_size = sysconf(_SC_PAGESIZE);
if (page_size == -1) {
error(status_vector, "sysconf", errno);
return NULL;
}
#else
const SLONG page_size = (int) getpagesize();
const ULONG page_size = (int) getpagesize();
if (page_size == -1) {
error(status_vector, "getpagesize", errno);
return NULL;
@ -2684,9 +2667,9 @@ UCHAR *ISC_map_object(ISC_STATUS * status_vector,
/* Compute the start and end page-aligned offsets which
contain the object being mapped. */
const SLONG start = (object_offset / page_size) * page_size;
const SLONG end = (((object_offset + object_length) / page_size) + 1) * page_size;
const SLONG length = end - start;
const ULONG start = (object_offset / page_size) * page_size;
const ULONG end = FB_ALIGN(object_offset + object_length, page_size);
const ULONG length = end - start;
int fd = shmem_data->sh_mem_handle;
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,
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. */
#ifdef SOLARIS
const SLONG page_size = sysconf(_SC_PAGESIZE);
const ULONG page_size = sysconf(_SC_PAGESIZE);
if (page_size == -1) {
error(status_vector, "sysconf", errno);
return; // false;
}
#else
const SLONG page_size = (int) getpagesize();
const ULONG page_size = (int) getpagesize();
if (page_size == -1) {
error(status_vector, "getpagesize", errno);
return; // false;
@ -2741,7 +2725,7 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
UCHAR* start = (UCHAR *) ((U_IPTR) * object_pointer & ~(page_size - 1));
const UCHAR* end =
(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) {
error(status_vector, "munmap", errno);
@ -2757,7 +2741,8 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
#ifdef WIN_NT
UCHAR* ISC_map_object(ISC_STATUS* status_vector,
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;
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
// contain the object being mapped.
const SLONG start = (object_offset / page_size) * page_size;
const SLONG end = (((object_offset + object_length) / page_size) + 1) * page_size;
const SLONG length = end - start;
const ULONG start = (object_offset / page_size) * page_size;
const ULONG end = FB_ALIGN(object_offset + object_length, page_size);
const ULONG length = end - start;
const HANDLE handle = shmem_data->sh_mem_object;
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,
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;
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
// contain the object being mapped.
@ -3623,8 +3609,10 @@ void ISC_mutex_set_spin_count (struct mtx *mutex, ULONG spins)
#ifdef UNIX
#ifdef HAVE_MMAP
#define ISC_REMAP_FILE_DEFINED
UCHAR *ISC_remap_file(ISC_STATUS * status_vector,
SH_MEM shmem_data, SLONG new_length, bool flag)
UCHAR *ISC_remap_file(ISC_STATUS* status_vector,
SH_MEM shmem_data,
ULONG new_length,
bool flag)
{
/**************************************
*
@ -3669,9 +3657,9 @@ UCHAR *ISC_remap_file(ISC_STATUS * status_vector,
#ifdef WIN_NT
#define ISC_REMAP_FILE_DEFINED
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)
{
/**************************************
*
@ -3686,7 +3674,7 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
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) ||
!FlushViewOfFile(shmem_data->sh_mem_address, 0))
{
@ -3709,16 +3697,15 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
HANDLE file_obj;
while (true) {
TEXT expanded_filename[MAXPATHLEN];
sprintf(expanded_filename, "%s%"SLONGFORMAT, shmem_data->sh_mem_name,
shmem_data->sh_mem_hdr_address[1] + 1);
TEXT mapping_name[MAXPATHLEN + 15]; // enough for int32 as text
sprintf(mapping_name, "%s_mapping_%"ULONGFORMAT,
shmem_data->sh_mem_name, shmem_data->sh_mem_hdr_address[1] + 1);
file_obj = CreateFileMapping(shmem_data->sh_mem_handle,
ISC_get_security_desc(),
PAGE_READWRITE,
0,
new_length,
expanded_filename);
ISC_get_security_desc(),
PAGE_READWRITE,
0, new_length,
mapping_name);
if (!((GetLastError() == ERROR_ALREADY_EXISTS) && flag))
break;
@ -3766,7 +3753,7 @@ UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
#ifndef ISC_REMAP_FILE_DEFINED
UCHAR* ISC_remap_file(ISC_STATUS * status_vector,
SH_MEM shmem_data,
SLONG new_length,
ULONG new_length,
bool flag)
{
/**************************************

View File

@ -861,9 +861,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
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 defined(DEV_BUILD) && defined(SUPERSERVER)
@ -891,19 +888,22 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
else
dbb->dbb_database_name = expanded_name;
// Extra LCK_init() done to keep the lock table until the
// database is shutdown() after the last detach.
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
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);
dbb->dbb_flags |= DBB_lck_init_done;
INI_init(tdbb);
PageSpace* pageSpace = dbb->dbb_page_manager.findPageSpace(DB_PAGE_SPACE);
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
LCK_init(tdbb, LCK_OWNER_attachment);
attachment->att_flags |= ATT_lck_init_done;
// Initialize locks
init_database_locks(tdbb);
INI_init(tdbb);
SHUT_init(tdbb);
PAG_header_init(tdbb);
INI_init2(tdbb);
@ -939,6 +939,11 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
// looks like someone tries to attach incompatibly
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
@ -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,
Attachment** handle,
SLONG* id)
ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS* user_status, Attachment** handle, SLONG* id)
{
/**************************************
*
@ -1383,7 +1386,12 @@ ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS* user_status,
DatabaseContextHolder dbbHolder(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)
{
@ -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;
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;
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;
// 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
init_database_locks(tdbb);
INI_init(tdbb);
PAG_init(tdbb);
initing_security = true;
SCL_init(tdbb, true, userId);
if (options.dpb_set_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();
Lock* const lock = dbb->dbb_lock;
EventManager::init(dbb);
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,
(const TEXT*) &lock->lck_key, length, items, ast, arg);
*id = dbb->dbb_event_mgr->queEvents(attachment->att_event_session,
lock->lck_length, (const TEXT*) &lock->lck_key,
length, items,
ast, arg);
}
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
TRA_init(dbb);
@ -4672,8 +4682,6 @@ static Database* init(thread_db* tdbb,
dbb->dbb_decrypt = (Database::crypt_routine) crypt_lib.lookupSymbol(decrypt_entrypoint);
}
INTL_init(tdbb);
return dbb;
}
@ -4838,8 +4846,10 @@ static void release_attachment(thread_db* tdbb, Attachment* attachment, ISC_STAT
}
#endif
if (attachment->att_event_session)
EVENT_delete_session(attachment->att_event_session);
if (dbb->dbb_event_mgr && attachment->att_event_session)
{
dbb->dbb_event_mgr->deleteSession(attachment->att_event_session);
}
if (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);
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;
}
@ -5088,8 +5098,6 @@ static void shutdown_database(Database* dbb, const bool release_pools)
CMP_fini(tdbb);
CCH_fini(tdbb);
DatabaseSnapshot::cleanup(tdbb);
if (dbb->dbb_backup_manager)
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) {
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;
}

View File

@ -39,6 +39,7 @@
#include "../common/classes/alloc.h"
#include "../common/classes/init.h"
#include "../common/classes/array.h"
#include "../jrd/ThreadStart.h"
#include <windows.h>
#include <process.h>

View File

@ -36,6 +36,7 @@
#include "../include/fb_blk.h"
#include "../common/classes/array.h"
#include "../jrd/ods.h"
namespace Jrd {

View File

@ -96,7 +96,7 @@
#include <process.h>
#define MUTEX &m_shmemMutex
#else
#define MUTEX m_header->lhb_mutex
#define MUTEX &m_header->lhb_mutex
#endif
#ifdef DEV_BUILD
@ -159,17 +159,12 @@ static const bool compatibility[LCK_max][LCK_max] =
namespace Jrd {
const char* LockManager::PATTERN = "firebird_db_%d_lock";
Firebird::GlobalPtr<LockManager::DbLockMgrMap> LockManager::g_lmMap;
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);
LockManager* lockMgr = NULL;
@ -180,26 +175,24 @@ LockManager* LockManager::create(const Firebird::PathName& filename)
fb_assert(lockMgr);
lockMgr->addRef();
return lockMgr;
}
LockManager::LockManager(int dbId)
LockManager::LockManager(const Firebird::string& id)
: PID(getpid()),
m_bugcheck(false),
m_header(NULL),
m_process(NULL),
m_processOffset(0),
m_dbId(dbId),
m_lockFile(getPool())
m_dbId(getPool(), id)
{
// m_lockFile.printf(PATTERN, m_dbId);
TEXT buffer[MAXPATHLEN];
gds__prefix_lock(buffer, LOCK_FILE);
m_lockFile = buffer;
Firebird::string name;
name.printf(LOCK_FILE, m_dbId.c_str());
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,
Config::getLockMemSize(),
&m_shmem)))
@ -207,6 +200,8 @@ LockManager::LockManager(int dbId)
Firebird::status_exception::raise(local_status);
}
fb_assert(m_header->lhb_version == LHB_VERSION);
Firebird::MutexLockGuard guard(g_mapMutex);
if (g_lmMap->put(m_dbId, this))
@ -251,10 +246,9 @@ LockManager::~LockManager()
release_mutex();
}
ISC_mutex_fini(MUTEX);
if (m_header)
{
ISC_mutex_fini(MUTEX);
ISC_unmap_file(local_status, &m_shmem);
}
@ -507,7 +501,7 @@ SRQ_PTR LockManager::enqueue(thread_db* tdbb,
else {
++m_header->lhb_operations[0];
}
insert_tail(&lock->lbl_requests, &request->lrq_lbl_requests);
request->lrq_data = data;
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
)
{
const SLONG length = m_header->lhb_length;
const ULONG new_length = m_header->lhb_length;
#if (defined HAVE_MMAP || defined WIN_NT)
Firebird::WriteLockGuard guard(m_remapSync);
@ -1070,7 +1064,7 @@ void LockManager::acquire_shmem(SRQ_PTR owner_offset)
remap_local_owners();
// Remap the shared memory region
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)
m_header = header;
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);
ASSERT_ACQUIRED;
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.
if (m_header->lhb_used > 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
)
if (m_header->lhb_used + size > m_header->lhb_length)
{
const bool extend = (m_header->lhb_used > m_header->lhb_length);
m_header->lhb_used -= size;
#if (defined HAVE_MMAP || defined WIN_NT)
Firebird::WriteLockGuard guard(m_remapSync);
// Post remapping notifications
remap_local_owners();
// Remap the shared memory region
const ULONG length = m_shmem.sh_mem_length_mapped + (extend ? Config::getLockMemSize() : 0);
lhb* header = (lhb*) ISC_remap_file(status_vector, &m_shmem, length, true);
const ULONG new_length = m_shmem.sh_mem_length_mapped + Config::getLockMemSize();
lhb* header = (lhb*) ISC_remap_file(status_vector, &m_shmem, new_length, true);
if (header) {
m_header = header;
ASSERT_ACQUIRED;
m_header->lhb_length = m_shmem.sh_mem_length_mapped;
m_header->lhb_used += size;
}
else
#endif
@ -1169,6 +1153,8 @@ UCHAR* LockManager::alloc(SSHORT size, ISC_STATUS* status_vector)
}
}
m_header->lhb_used += size;
#ifdef DEV_BUILD
// This version of alloc() doesn't initialize memory. To shake out
// 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()
{
/**************************************
@ -1334,14 +1312,12 @@ void LockManager::blocking_action_thread()
try
{
SRQ_PTR* process_offset_ptr = (SRQ_PTR*) &m_processOffset;
while (true)
{
m_localMutex.enter();
// 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)
{
@ -1357,7 +1333,7 @@ void LockManager::blocking_action_thread()
Firebird::HalfStaticArray<SRQ_PTR, 4> blocking_owners;
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_LOOP(process->prc_owners, lock_srq)
@ -1368,7 +1344,7 @@ void LockManager::blocking_action_thread()
release_mutex();
while (blocking_owners.getCount() && *process_offset_ptr)
while (blocking_owners.getCount() && m_processOffset)
{
const SRQ_PTR owner_offset = blocking_owners.pop();
acquire_shmem(owner_offset);
@ -1466,6 +1442,18 @@ void LockManager::bug(ISC_STATUS* status_vector, const TEXT* string)
{
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 (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)
{
TEXT bug_buffer[BUFFER_TINY];
sprintf(bug_buffer,
"inconsistent lock table version number; found %d, expected %d",
sprintf(bug_buffer, "inconsistent lock table version number; found %d, expected %d",
m_header->lhb_version, LHB_VERSION);
bug(status_vector, bug_buffer);
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_owner_id = owner_id;
owner->own_process = m_processOffset;
owner->own_thread_id = 0;
SRQ_INIT(owner->own_lhb_owners);
SRQ_INIT(owner->own_prc_owners);
SRQ_INIT(owner->own_requests);
@ -2177,7 +2165,7 @@ void LockManager::initialize(SH_MEM shmem_data, bool initialize)
*
**************************************/
#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");
}
#endif
@ -2236,7 +2224,7 @@ void LockManager::initialize(SH_MEM shmem_data, bool initialize)
if (Config::getLockGrantOrder())
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_used = FB_ALIGN(length, FB_ALIGNMENT);

View File

@ -90,14 +90,12 @@ const SSHORT LCK_NO_WAIT = 0;
const UCHAR type_null = 0;
const UCHAR type_lhb = 1;
const UCHAR type_prb = 2;
const UCHAR type_lrq = 3;
const UCHAR type_lbl = 4;
const UCHAR type_his = 5;
const UCHAR type_smbx = 6;
const UCHAR type_shb = 7;
const UCHAR type_own = 8;
const UCHAR type_lpr = 9;
const UCHAR type_lrq = 2;
const UCHAR type_lbl = 3;
const UCHAR type_his = 4;
const UCHAR type_shb = 5;
const UCHAR type_own = 6;
const UCHAR type_lpr = 7;
const UCHAR type_MAX = type_lpr;
// Version number of the lock table.
@ -134,11 +132,11 @@ struct lhb
srq lhb_free_owners; // Free owner blocks
srq lhb_free_locks; // Free lock blocks
srq lhb_free_requests; // Free lock requests
SLONG lhb_length; // Size of lock table
SLONG lhb_used; // Bytes of lock table in use
ULONG lhb_length; // Size of lock table
ULONG lhb_used; // Bytes of lock table in use
USHORT lhb_hash_slots; // Number of hash slots allocated
USHORT lhb_flags; // Miscellaneous info
mtx lhb_mutex[1]; // Mutex controlling access
struct mtx lhb_mutex; // Mutex controlling access
SRQ_PTR lhb_history;
ULONG lhb_scan_interval; // Deadlock scan interval (secs)
ULONG lhb_acquire_spins;

View File

@ -43,16 +43,15 @@ class thread_db;
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<Firebird::Mutex> g_mapMutex;
static const char* PATTERN;
const int PID;
public:
static LockManager* create(const Firebird::PathName&);
static LockManager* create(const Firebird::string&);
bool initializeOwner(thread_db*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
void shutdownOwner(thread_db*, SRQ_PTR*);
@ -72,7 +71,7 @@ public:
SLONG writeData(SRQ_PTR, SLONG);
private:
explicit LockManager(int);
explicit LockManager(const Firebird::string&);
~LockManager();
bool lockOrdering() const
@ -81,7 +80,7 @@ private:
}
void acquire_shmem(SRQ_PTR);
UCHAR* alloc(SSHORT, ISC_STATUS*);
UCHAR* alloc(USHORT, ISC_STATUS*);
lbl* alloc_lock(USHORT, ISC_STATUS*);
void blocking_action(thread_db*, SRQ_PTR, SRQ_PTR);
void blocking_action_thread();
@ -133,7 +132,12 @@ private:
#endif
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)
{
@ -155,8 +159,7 @@ private:
Firebird::Semaphore m_cleanupSemaphore;
Firebird::Semaphore m_startupSemaphore;
const int m_dbId;
Firebird::PathName m_lockFile;
Firebird::string m_dbId;
#ifdef WIN_NT
struct mtx m_shmemMutex;

View File

@ -67,6 +67,8 @@ const char* INTERBASE_USER = "interbase";
const char* FIREBIRD_USER = "firebird";
const char* INTERBASE_USER_SHORT= "interbas";
const char* GUARD_FILE = "fb_guard";
volatile sig_atomic_t shutting_down;

View File

@ -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 */
gds__prefix_lock(tmp, file);
sprintf(expanded_filename, tmp, ISC_get_host(hostname, sizeof(hostname)));
gds__prefix(expanded_filename, file);
/* file fd for the opened and locked file */
int fd_file = open(expanded_filename, O_RDWR | O_CREAT, 0666);