2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD access method
|
|
|
|
* MODULE: jrd.h
|
|
|
|
* DESCRIPTION: Common descriptions
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-10-29 04:17:45 +01:00
|
|
|
*
|
|
|
|
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "DecOSF" port
|
|
|
|
*
|
2002-10-30 07:40:58 +01:00
|
|
|
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef JRD_JRD_H
|
|
|
|
#define JRD_JRD_H
|
|
|
|
|
2004-03-24 12:06:22 +01:00
|
|
|
#include "../jrd/gdsassert.h"
|
2004-03-28 11:10:30 +02:00
|
|
|
#include "../jrd/common.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/dsc.h"
|
2001-12-24 03:51:06 +01:00
|
|
|
#include "../jrd/all.h"
|
2004-03-20 15:57:40 +01:00
|
|
|
#include "../jrd/btn.h"
|
2004-06-22 22:13:10 +02:00
|
|
|
#include "../jrd/all.h"
|
2004-08-30 20:11:08 +02:00
|
|
|
#include "../jrd/jrd_proto.h"
|
2003-11-18 14:46:27 +01:00
|
|
|
#if defined(UNIX) && defined(SUPERSERVER)
|
|
|
|
#include <setjmp.h>
|
|
|
|
#endif
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2004-12-17 06:41:47 +01:00
|
|
|
#include "../common/classes/fb_string.h"
|
2005-05-12 20:28:04 +02:00
|
|
|
#include "../common/classes/MetaName.h"
|
2006-04-25 19:49:24 +02:00
|
|
|
#include "../common/classes/array.h"
|
2004-04-19 17:29:29 +02:00
|
|
|
#include "../common/classes/objects_array.h"
|
2004-06-22 22:13:10 +02:00
|
|
|
#include "../common/classes/stack.h"
|
2004-10-30 21:41:54 +02:00
|
|
|
#include "../common/classes/timestamp.h"
|
2004-11-24 21:48:59 +01:00
|
|
|
#include "../common/classes/GenericMap.h"
|
2007-10-28 15:54:16 +01:00
|
|
|
#include "../jrd/RandomGenerator.h"
|
2006-10-30 13:39:08 +01:00
|
|
|
#include "../jrd/os/guid.h"
|
2004-11-05 09:01:21 +01:00
|
|
|
#include "../jrd/sbm.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
#define DEBUG if (debug) DBG_supervisor(debug);
|
2006-02-23 06:08:26 +01:00
|
|
|
//#define VIO_DEBUG // remove this for production build
|
2006-07-21 03:35:17 +02:00
|
|
|
#else // PROD
|
2001-05-23 15:26:42 +02:00
|
|
|
#define DEBUG
|
|
|
|
#undef VIO_DEBUG
|
|
|
|
#endif
|
|
|
|
|
2004-09-24 02:11:32 +02:00
|
|
|
#define BUGCHECK(number) ERR_bugcheck (number, __FILE__, __LINE__)
|
2001-05-23 15:26:42 +02:00
|
|
|
#define CORRUPT(number) ERR_corrupt (number)
|
|
|
|
#define IBERROR(number) ERR_error (number)
|
|
|
|
|
2002-07-29 17:37:59 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
#define BLKCHK(blk, type) if (MemoryPool::blk_type(blk) != (USHORT) (type)) BUGCHECK (147)
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/* DEV_BLKCHK is used for internal consistency checking - where
|
|
|
|
* the performance hit in production build isn't desired.
|
|
|
|
* (eg: scatter this everywhere)
|
2002-07-29 17:37:59 +02:00
|
|
|
*
|
|
|
|
* This causes me a problem DEV_BLKCHK fails when the data seems valid
|
|
|
|
* After talking to John this could be because the memory is from the local
|
|
|
|
* stack rather than the heap. However I found to continue I needed to
|
|
|
|
* turn it off by dfining the macro to be empty. But In thinking about
|
|
|
|
* it I think that it would be more helful for a mode where these extra
|
|
|
|
* DEV checks just gave warnings rather than being fatal.
|
|
|
|
* MOD 29-July-2002
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
#ifdef DEV_BUILD
|
2002-09-11 21:37:30 +02:00
|
|
|
#define DEV_BLKCHK(blk,type)
|
2004-11-24 10:22:07 +01:00
|
|
|
//#define DEV_BLKCHK(blk, type) if (blk) {BLKCHK (blk, type);}
|
2001-05-23 15:26:42 +02:00
|
|
|
#else
|
2006-02-23 06:08:26 +01:00
|
|
|
#define DEV_BLKCHK(blk, type) // nothing
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
// Thread data block / IPC related data blocks
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/thd.h"
|
|
|
|
#include "../jrd/isc.h"
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
// Definition of block types for data allocation in JRD
|
2001-12-24 03:51:06 +01:00
|
|
|
#include "../jrd/jrd_blks.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../include/fb_blk.h"
|
|
|
|
|
2006-10-30 21:58:06 +01:00
|
|
|
#include "../jrd/blb.h"
|
|
|
|
|
2004-11-29 12:15:09 +01:00
|
|
|
// Definition of DatabasePlugins
|
|
|
|
#include "../jrd/flu.h"
|
|
|
|
|
2006-05-22 00:07:35 +02:00
|
|
|
#include "../jrd/pag.h"
|
|
|
|
|
2006-10-07 12:53:01 +02:00
|
|
|
#include "../jrd/RuntimeStatistics.h"
|
|
|
|
|
2006-05-22 00:07:35 +02:00
|
|
|
class str;
|
2004-03-20 15:57:40 +01:00
|
|
|
class CharSetContainer;
|
2004-03-28 11:10:30 +02:00
|
|
|
struct dsc;
|
2004-04-20 07:57:31 +02:00
|
|
|
struct thread;
|
2004-04-18 16:22:27 +02:00
|
|
|
struct mod;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
namespace Jrd {
|
2004-02-25 02:50:40 +01:00
|
|
|
|
2006-10-07 12:53:01 +02:00
|
|
|
const int HASH_SIZE = 509;
|
2001-12-28 07:31:38 +01:00
|
|
|
|
|
|
|
// fwd. decl.
|
2005-12-02 08:35:34 +01:00
|
|
|
//class vec;
|
|
|
|
template <typename T> class vec;
|
2004-06-08 15:41:08 +02:00
|
|
|
class thread_db;
|
2004-03-18 06:56:06 +01:00
|
|
|
class Attachment;
|
2004-02-20 07:43:27 +01:00
|
|
|
class jrd_tra;
|
|
|
|
class jrd_req;
|
2004-03-18 06:56:06 +01:00
|
|
|
class Lock;
|
2004-02-20 07:43:27 +01:00
|
|
|
class jrd_file;
|
2004-03-30 06:10:52 +02:00
|
|
|
class Format;
|
2004-03-11 06:04:26 +01:00
|
|
|
class jrd_nod;
|
2004-03-18 06:56:06 +01:00
|
|
|
class BufferControl;
|
2005-11-22 00:33:20 +01:00
|
|
|
class BackupManager;
|
2004-03-18 06:56:06 +01:00
|
|
|
class SparseBitmap;
|
|
|
|
class BlockingThread;
|
|
|
|
class jrd_rel;
|
|
|
|
class ExternalFile;
|
|
|
|
class ViewContext;
|
2004-03-19 07:14:53 +01:00
|
|
|
class IndexBlock;
|
|
|
|
class IndexLock;
|
|
|
|
class ArrayField;
|
|
|
|
class BlobFilter;
|
|
|
|
class PageControl;
|
|
|
|
class Symbol;
|
|
|
|
class UserId;
|
|
|
|
struct sort_context;
|
|
|
|
class TxPageCache;
|
2004-03-28 11:10:30 +02:00
|
|
|
class RecordSelExpr;
|
|
|
|
class SecurityClass;
|
|
|
|
class vcl;
|
|
|
|
class Shadow;
|
2004-03-20 15:57:40 +01:00
|
|
|
class TextType;
|
2005-12-02 08:35:34 +01:00
|
|
|
class jrd_prc;
|
|
|
|
class Parameter;
|
|
|
|
class jrd_fld;
|
2001-12-28 07:31:38 +01:00
|
|
|
|
2006-10-07 12:53:01 +02:00
|
|
|
// The database block, the topmost block in the metadata
|
|
|
|
// cache for a database
|
|
|
|
|
2006-11-05 19:30:36 +01:00
|
|
|
// Relation trigger definition
|
|
|
|
|
|
|
|
class Trigger {
|
|
|
|
public:
|
|
|
|
Firebird::HalfStaticArray<UCHAR, 128> blr; // BLR code
|
|
|
|
bid dbg_blob_id; // RDB$DEBUG_INFO
|
|
|
|
jrd_req* request; // Compiled request. Gets filled on first invocation
|
|
|
|
bool compile_in_progress;
|
|
|
|
bool sys_trigger;
|
|
|
|
UCHAR type; // Trigger type
|
|
|
|
USHORT flags; // Flags as they are in RDB$TRIGGERS table
|
|
|
|
jrd_rel* relation; // Trigger parent relation
|
|
|
|
Firebird::MetaName name; // Trigger name
|
|
|
|
void compile(thread_db*); // Ensure that trigger is compiled
|
|
|
|
void release(thread_db*); // Try to free trigger request
|
|
|
|
|
|
|
|
explicit Trigger(MemoryPool& p) : blr(p), name(p)
|
|
|
|
{ dbg_blob_id.clear(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Firebird::ObjectsArray<Trigger> trig_vec;
|
|
|
|
|
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
class Database : private pool_alloc<type_dbb>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2004-03-14 14:34:43 +01:00
|
|
|
typedef int (*crypt_routine) (const char*, void*, int, void*);
|
2003-02-09 11:05:07 +01:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
static Database* newDbb(MemoryPool& p) {
|
|
|
|
return FB_NEW(p) Database(p);
|
2003-01-16 18:47:10 +01:00
|
|
|
}
|
2002-09-22 19:25:46 +02:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
// The deleteDbb function MUST be used to delete a Database object.
|
2002-09-22 21:08:33 +02:00
|
|
|
// The function hides some tricky order of operations. Since the
|
2004-03-07 08:58:55 +01:00
|
|
|
// memory for the vectors in the Database is allocated out of the Database's
|
2002-09-22 21:08:33 +02:00
|
|
|
// permanent memory pool, the entire delete() operation needs
|
|
|
|
// to complete _before_ the permanent pool is deleted, or else
|
|
|
|
// risk an aborted engine.
|
2004-03-07 08:58:55 +01:00
|
|
|
static void deleteDbb(Database* toDelete)
|
2002-09-22 19:25:46 +02:00
|
|
|
{
|
2002-09-22 21:08:33 +02:00
|
|
|
if (toDelete == 0)
|
|
|
|
return;
|
|
|
|
JrdMemoryPool *perm = toDelete->dbb_permanent;
|
2004-08-17 04:02:21 +02:00
|
|
|
#ifdef SUPERSERVER
|
|
|
|
// Memory pool destruction below decrements memory statistics for
|
|
|
|
// SuperServer situated in database block we are about to deallocate
|
|
|
|
// right now.
|
|
|
|
Firebird::MemoryStats temp_stats;
|
|
|
|
perm->setStatsGroup(temp_stats);
|
|
|
|
#endif
|
2002-09-22 21:08:33 +02:00
|
|
|
delete toDelete;
|
2003-11-20 22:53:07 +01:00
|
|
|
JrdMemoryPool::noDbbDeletePool(perm);
|
2002-09-22 19:25:46 +02:00
|
|
|
}
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
Database* dbb_next; // Next database block in system
|
|
|
|
Attachment* dbb_attachments; // Active attachments
|
|
|
|
BufferControl* dbb_bcb; // Buffer control block
|
|
|
|
vec<jrd_rel*>* dbb_relations; // relation vector
|
|
|
|
vec<jrd_prc*>* dbb_procedures; // scanned procedures
|
2006-10-30 13:39:08 +01:00
|
|
|
FB_GUID dbb_guid; // dbb instance identifier
|
|
|
|
Lock* dbb_instance_lock; // dbb instance lock
|
2006-07-21 03:35:17 +02:00
|
|
|
Lock* dbb_lock; // granddaddy 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
|
2006-10-07 12:53:01 +02:00
|
|
|
Lock* dbb_monitor_lock; // lock for monitoring purposes
|
2006-05-22 00:07:35 +02:00
|
|
|
PageManager dbb_page_manager;
|
2006-07-21 03:35:17 +02:00
|
|
|
vcl* dbb_t_pages; // pages number for transactions
|
|
|
|
vcl* dbb_gen_id_pages; // known pages for gen_id
|
|
|
|
BlobFilter* dbb_blob_filters; // known blob filters
|
2006-11-05 19:30:36 +01:00
|
|
|
trig_vec* dbb_triggers[DB_TRIGGER_MAX];
|
2006-02-23 06:08:26 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
DatabaseModules modules; // external function/filter modules
|
2007-06-07 05:35:04 +02:00
|
|
|
Firebird::Mutex* dbb_mutexes; // Database block mutexes
|
2006-07-21 03:35:17 +02:00
|
|
|
REC_MUTX_T dbb_sp_rec_mutex; // Recursive mutex for accessing/updating stored procedure metadata
|
|
|
|
//SLONG dbb_sort_size; // Size of sort space per sort, unused for now
|
2006-02-23 06:08:26 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
UATOM dbb_ast_flags; // flags modified at AST level
|
2001-05-23 15:26:42 +02:00
|
|
|
ULONG dbb_flags;
|
2006-07-21 03:35:17 +02:00
|
|
|
USHORT dbb_ods_version; // major ODS version number
|
|
|
|
USHORT dbb_minor_version; // minor ODS version number
|
|
|
|
USHORT dbb_minor_original; // minor ODS version at creation
|
|
|
|
USHORT dbb_page_size; // page size
|
|
|
|
USHORT dbb_dp_per_pp; // data pages per pointer page
|
|
|
|
USHORT dbb_max_records; // max record per data page
|
|
|
|
USHORT dbb_max_idx; // max number of indexes on a root page
|
|
|
|
USHORT dbb_use_count; // active count of threads
|
|
|
|
USHORT dbb_shutdown_delay; // seconds until forced shutdown.
|
|
|
|
// Set in shut.cpp but not tested yet.
|
2006-02-03 03:28:58 +01:00
|
|
|
#ifdef SUPERSERVER_V2
|
2006-07-21 03:35:17 +02:00
|
|
|
USHORT dbb_prefetch_sequence; // sequence to pace frequency of prefetch requests
|
|
|
|
USHORT dbb_prefetch_pages; // prefetch pages per request
|
2006-02-03 03:28:58 +01:00
|
|
|
#endif
|
2006-02-23 06:08:26 +01:00
|
|
|
Firebird::PathName dbb_filename; // filename string
|
|
|
|
Firebird::PathName dbb_database_name; // database ID (file name or alias)
|
|
|
|
Firebird::string dbb_encrypt_key; // encryption key
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
JrdMemoryPool* dbb_permanent;
|
|
|
|
JrdMemoryPool* dbb_bufferpool;
|
|
|
|
|
|
|
|
typedef JrdMemoryPool* pool_ptr;
|
2006-04-25 19:49:24 +02:00
|
|
|
typedef Firebird::Array<pool_ptr> pool_vec_type;
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
pool_vec_type dbb_pools; // pools
|
2006-02-03 03:28:58 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
vec<jrd_req*>* dbb_internal; // internal requests
|
|
|
|
vec<jrd_req*>* dbb_dyn_req; // internal dyn requests
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
SLONG dbb_oldest_active; // Cached "oldest active" transaction
|
|
|
|
SLONG dbb_oldest_transaction; // Cached "oldest interesting" transaction
|
|
|
|
SLONG dbb_oldest_snapshot; // Cached "oldest snapshot" of all active transactions
|
|
|
|
SLONG dbb_next_transaction; // Next transaction id used by NETWARE
|
|
|
|
SLONG dbb_attachment_id; // Next attachment id for ReadOnly DB's
|
|
|
|
SLONG dbb_page_incarnation; // Cache page incarnation counter
|
|
|
|
ULONG dbb_page_buffers; // Page buffers from header page
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
event_t dbb_writer_event[1]; // Event to wake up cache writer
|
2006-02-23 06:08:26 +01:00
|
|
|
event_t dbb_writer_event_init[1]; // Event for initialization cache writer
|
|
|
|
event_t dbb_writer_event_fini[1]; // Event for finalization cache writer
|
2006-02-03 03:28:58 +01:00
|
|
|
#ifdef SUPERSERVER_V2
|
2006-07-21 03:35:17 +02:00
|
|
|
event_t dbb_reader_event[1]; // Event to wake up cache reader
|
2006-02-03 03:28:58 +01:00
|
|
|
#endif
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef GARBAGE_THREAD
|
2006-07-21 03:35:17 +02:00
|
|
|
event_t dbb_gc_event[1]; // Event to wake up garbage collector
|
|
|
|
event_t dbb_gc_event_init[1]; // Event for initialization garbage collector
|
|
|
|
event_t dbb_gc_event_fini[1]; // Event for finalization garbage collector
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2006-02-03 03:28:58 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
BlockingThread* dbb_free_btbs; // Unused BlockingThread blocks
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2007-09-05 09:18:37 +02:00
|
|
|
ULONG dbb_current_id; // Generator of dbb-local ids
|
2004-03-26 00:12:50 +01:00
|
|
|
Firebird::MemoryStats dbb_memory_stats;
|
2006-10-07 12:53:01 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
SLONG dbb_reads;
|
|
|
|
SLONG dbb_writes;
|
|
|
|
SLONG dbb_fetches;
|
|
|
|
SLONG dbb_marks;
|
2006-10-07 12:53:01 +02:00
|
|
|
RuntimeStatistics dbb_stats;
|
2006-07-21 03:35:17 +02:00
|
|
|
SLONG dbb_last_header_write; // Transaction id of last header page physical write
|
|
|
|
SLONG dbb_flush_cycle; // Current flush cycle
|
|
|
|
SLONG dbb_sweep_interval; // Transactions between sweep
|
|
|
|
SLONG dbb_lock_owner_handle; // Handle for the lock manager
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
USHORT unflushed_writes; // unflushed writes
|
|
|
|
time_t last_flushed_write; // last flushed write time
|
2003-02-05 21:43:01 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
crypt_routine dbb_encrypt; // External encryption routine
|
|
|
|
crypt_routine dbb_decrypt; // External decryption routine
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-02-03 03:28:58 +01:00
|
|
|
#ifdef REPLAY_OSRI_API_CALLS_SUBSYSTEM
|
2006-07-21 03:35:17 +02:00
|
|
|
class blb_map *dbb_blob_map; // mapping of blobs for REPLAY
|
|
|
|
struct log *dbb_log; // log file for REPLAY
|
2006-02-03 03:28:58 +01:00
|
|
|
#endif
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
Firebird::Array<CharSetContainer*> dbb_charsets; // intl character set descriptions
|
|
|
|
TxPageCache* dbb_tip_cache; // cache of latest known state of all transactions in system
|
|
|
|
vcl* dbb_pc_transactions; // active precommitted transactions
|
|
|
|
BackupManager *dbb_backup_manager; // physical backup manager
|
|
|
|
Firebird::TimeStamp dbb_creation_date; // creation date
|
|
|
|
Symbol* dbb_hash_table[HASH_SIZE]; // keep this at the end
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2007-09-05 09:18:37 +02:00
|
|
|
ULONG generateId()
|
|
|
|
{
|
|
|
|
return ++dbb_current_id;
|
|
|
|
}
|
|
|
|
|
2007-10-26 15:21:16 +02:00
|
|
|
// returns true if primary file is located on raw device
|
|
|
|
bool onRawDevice();
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
private:
|
2004-03-31 20:03:51 +02:00
|
|
|
explicit Database(MemoryPool& p)
|
2006-05-22 12:41:32 +02:00
|
|
|
: dbb_page_manager(p),
|
|
|
|
modules(p),
|
2004-03-14 14:34:43 +01:00
|
|
|
dbb_filename(p),
|
2004-11-11 06:37:52 +01:00
|
|
|
dbb_database_name(p),
|
2004-03-19 12:21:59 +01:00
|
|
|
dbb_encrypt_key(p),
|
2006-04-25 19:49:24 +02:00
|
|
|
dbb_pools(p, 4),
|
2006-10-08 03:57:21 +02:00
|
|
|
dbb_charsets(p)
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
2006-04-25 19:49:24 +02:00
|
|
|
dbb_pools.resize(1);
|
2001-12-24 03:51:06 +01:00
|
|
|
}
|
2003-01-20 12:10:30 +01:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
~Database()
|
2002-09-22 21:08:33 +02:00
|
|
|
{
|
2005-05-28 00:45:31 +02:00
|
|
|
destroyIntlObjects();
|
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
pool_ptr* itr = dbb_pools.begin();
|
2003-01-20 12:10:30 +01:00
|
|
|
while (itr != dbb_pools.end())
|
2002-09-22 21:08:33 +02:00
|
|
|
{
|
2003-01-20 12:10:30 +01:00
|
|
|
if (*itr && *itr == dbb_bufferpool)
|
2002-09-22 21:08:33 +02:00
|
|
|
dbb_bufferpool = 0;
|
2003-01-16 18:47:10 +01:00
|
|
|
if (*itr && *itr != dbb_permanent)
|
2006-10-31 13:27:49 +01:00
|
|
|
itr = JrdMemoryPool::deletePool(*itr);
|
2003-01-20 12:10:30 +01:00
|
|
|
else
|
2006-02-10 04:28:43 +01:00
|
|
|
++itr;
|
2002-09-22 21:08:33 +02:00
|
|
|
}
|
2003-01-20 12:10:30 +01:00
|
|
|
if (dbb_bufferpool)
|
2003-01-16 18:47:10 +01:00
|
|
|
JrdMemoryPool::deletePool(dbb_bufferpool);
|
2002-09-22 21:08:33 +02:00
|
|
|
}
|
2003-01-20 12:10:30 +01:00
|
|
|
|
2007-07-25 15:21:59 +02:00
|
|
|
// temporal measure to avoid unstable state of lock file -
|
|
|
|
// this is anyway called in ~Database(), and in theory should be private
|
|
|
|
public:
|
2006-07-21 03:35:17 +02:00
|
|
|
void destroyIntlObjects(); // defined in intl.cpp
|
2007-07-25 15:21:59 +02:00
|
|
|
private:
|
2005-05-28 00:45:31 +02:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
// The delete operators are no-oped because the Database memory is allocated from the
|
|
|
|
// Database's own permanent pool. That pool has already been released by the Database
|
2002-09-22 21:08:33 +02:00
|
|
|
// destructor, so the memory has already been released. Hence the operator
|
|
|
|
// delete no-op.
|
|
|
|
void operator delete(void *mem) {}
|
|
|
|
void operator delete[](void *mem) {}
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
Database(const Database&); // no impl.
|
2004-03-07 08:58:55 +01:00
|
|
|
const Database& operator =(const Database&) { return *this; }
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// bit values for dbb_flags
|
|
|
|
//
|
2006-02-23 06:08:26 +01:00
|
|
|
//const ULONG DBB_no_garbage_collect = 0x1L; // Obsolete.
|
2004-04-29 16:51:02 +02:00
|
|
|
const ULONG DBB_damaged = 0x2L;
|
2006-07-21 03:35:17 +02:00
|
|
|
const ULONG DBB_exclusive = 0x4L; // Database is accessed in exclusive mode
|
|
|
|
const ULONG DBB_bugcheck = 0x8L; // Bugcheck has occurred
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef GARBAGE_THREAD
|
2006-07-21 03:35:17 +02:00
|
|
|
const ULONG DBB_garbage_collector = 0x10L; // garbage collector thread exists
|
|
|
|
const ULONG DBB_gc_active = 0x20L; // ... and is actively working.
|
|
|
|
const ULONG DBB_gc_pending = 0x40L; // garbage collection requested
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
2006-07-21 03:35:17 +02:00
|
|
|
const ULONG DBB_force_write = 0x80L; // Database is forced write
|
|
|
|
const ULONG DBB_no_reserve = 0x100L; // No reserve space for versions
|
2007-07-26 09:37:09 +02:00
|
|
|
const ULONG DBB_no_fs_cache = 0x200L; // Not using file system cache
|
2004-10-03 06:49:04 +02:00
|
|
|
//const ULONG DBB_add_log = 0x200L; // write ahead log has been added
|
|
|
|
//const ULONG DBB_delete_log = 0x400L; // write ahead log has been deleted
|
|
|
|
//const ULONG DBB_cache_manager = 0x800L; // Shared cache manager
|
2006-07-21 03:35:17 +02:00
|
|
|
const ULONG DBB_DB_SQL_dialect_3 = 0x1000L; // database SQL dialect 3
|
|
|
|
const ULONG DBB_read_only = 0x2000L; // DB is ReadOnly (RO). If not set, DB is RW
|
|
|
|
const ULONG DBB_being_opened_read_only = 0x4000L; // DB is being opened RO. If unset, opened as RW
|
|
|
|
const ULONG DBB_not_in_use = 0x8000L; // Database to be ignored while attaching
|
|
|
|
const ULONG DBB_lck_init_done = 0x10000L; // LCK_init() called for the database
|
|
|
|
const ULONG DBB_sp_rec_mutex_init = 0x20000L; // Stored procedure mutex initialized
|
|
|
|
const ULONG DBB_sweep_in_progress = 0x40000L; // A database sweep operation is in progress
|
|
|
|
const ULONG DBB_security_db = 0x80000L; // ISC security database
|
2006-02-23 06:08:26 +01:00
|
|
|
//const ULONG DBB_sweep_thread_started = 0x100000L; // A database sweep thread has been started
|
2006-07-21 03:35:17 +02:00
|
|
|
const ULONG DBB_suspend_bgio = 0x200000L; // Suspend I/O by background threads
|
|
|
|
const ULONG DBB_being_opened = 0x400000L; // database is being attached to
|
|
|
|
const ULONG DBB_gc_cooperative = 0x0800000L; // cooperative garbage collection
|
|
|
|
const ULONG DBB_gc_background = 0x1000000L; // background garbage collection by gc_thread
|
2007-01-20 15:45:45 +01:00
|
|
|
#if (defined DEV_BUILD && !defined MULTI_THREAD)
|
2007-01-26 11:31:22 +01:00
|
|
|
const ULONG DBB_exec_statement = 0x2000000L; // execute statement runs against database
|
2007-01-20 15:45:45 +01:00
|
|
|
#endif
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// dbb_ast_flags
|
|
|
|
//
|
2004-05-04 00:42:47 +02:00
|
|
|
const UATOM DBB_blocking = 0x1L; // Exclusive mode is blocking
|
|
|
|
const UATOM DBB_get_shadows = 0x2L; // Signal received to check for new shadows
|
|
|
|
const UATOM DBB_assert_locks = 0x4L; // Locks are to be asserted
|
|
|
|
const UATOM DBB_shutdown = 0x8L; // Database is shutdown
|
|
|
|
const UATOM DBB_shut_attach = 0x10L; // no new attachments accepted
|
|
|
|
const UATOM DBB_shut_tran = 0x20L; // no new transactions accepted
|
|
|
|
const UATOM DBB_shut_force = 0x40L; // forced shutdown in progress
|
|
|
|
const UATOM DBB_shutdown_locks = 0x80L; // Database locks release by shutdown
|
|
|
|
const UATOM DBB_shutdown_full = 0x100L; // Database fully shut down
|
|
|
|
const UATOM DBB_shutdown_single = 0x200L; // Database is in single-user maintenance mode
|
2006-10-30 13:39:08 +01:00
|
|
|
const UATOM DBB_monitor_off = 0x400L; // Database has the monitoring lock released
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// Database attachments
|
|
|
|
//
|
2004-04-29 16:51:02 +02:00
|
|
|
const int DBB_read_seq_count = 0;
|
|
|
|
const int DBB_read_idx_count = 1;
|
|
|
|
const int DBB_update_count = 2;
|
|
|
|
const int DBB_insert_count = 3;
|
|
|
|
const int DBB_delete_count = 4;
|
|
|
|
const int DBB_backout_count = 5;
|
|
|
|
const int DBB_purge_count = 6;
|
|
|
|
const int DBB_expunge_count = 7;
|
|
|
|
const int DBB_max_count = 8;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
2006-05-01 06:42:10 +02:00
|
|
|
// Database mutexes
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
2004-04-29 16:51:02 +02:00
|
|
|
const int DBB_MUTX_init_fini = 0; // During startup and shutdown
|
2006-02-23 06:08:26 +01:00
|
|
|
//const int DBB_MUTX_statistics = 1; // Memory size and counts
|
|
|
|
//const int DBB_MUTX_replay = 2; // Replay logging
|
2004-04-29 16:51:02 +02:00
|
|
|
const int DBB_MUTX_dyn = 3; // Dynamic ddl
|
2006-02-23 06:08:26 +01:00
|
|
|
//const int DBB_MUTX_cache = 4; // Process-private cache management
|
2004-04-29 16:51:02 +02:00
|
|
|
const int DBB_MUTX_clone = 5; // Request cloning
|
|
|
|
const int DBB_MUTX_cmp_clone = 6; // Compiled request cloning
|
|
|
|
const int DBB_MUTX_flush_count = 7; // flush count/time
|
|
|
|
const int DBB_MUTX_max = 8;
|
2006-02-23 06:08:26 +01:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// Flags to indicate normal internal requests vs. dyn internal requests
|
|
|
|
//
|
2004-04-29 16:51:02 +02:00
|
|
|
const int IRQ_REQUESTS = 1;
|
|
|
|
const int DYN_REQUESTS = 2;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// Errors during validation - will be returned on info calls
|
2003-12-11 11:33:30 +01:00
|
|
|
// CVC: It seems they will be better in a header for val.cpp that's not val.h
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
2004-04-29 16:51:02 +02:00
|
|
|
const int VAL_PAG_WRONG_TYPE = 0;
|
|
|
|
const int VAL_PAG_CHECKSUM_ERR = 1;
|
|
|
|
const int VAL_PAG_DOUBLE_ALLOC = 2;
|
|
|
|
const int VAL_PAG_IN_USE = 3;
|
|
|
|
const int VAL_PAG_ORPHAN = 4;
|
|
|
|
const int VAL_BLOB_INCONSISTENT = 5;
|
|
|
|
const int VAL_BLOB_CORRUPT = 6;
|
|
|
|
const int VAL_BLOB_TRUNCATED = 7;
|
|
|
|
const int VAL_REC_CHAIN_BROKEN = 8;
|
|
|
|
const int VAL_DATA_PAGE_CONFUSED = 9;
|
|
|
|
const int VAL_DATA_PAGE_LINE_ERR = 10;
|
|
|
|
const int VAL_INDEX_PAGE_CORRUPT = 11;
|
|
|
|
const int VAL_P_PAGE_LOST = 12;
|
|
|
|
const int VAL_P_PAGE_INCONSISTENT = 13;
|
|
|
|
const int VAL_REC_DAMAGED = 14;
|
|
|
|
const int VAL_REC_BAD_TID = 15;
|
|
|
|
const int VAL_REC_FRAGMENT_CORRUPT = 16;
|
|
|
|
const int VAL_REC_WRONG_LENGTH = 17;
|
|
|
|
const int VAL_INDEX_ROOT_MISSING = 18;
|
|
|
|
const int VAL_TIP_LOST = 19;
|
|
|
|
const int VAL_TIP_LOST_SEQUENCE = 20;
|
|
|
|
const int VAL_TIP_CONFUSED = 21;
|
|
|
|
const int VAL_REL_CHAIN_ORPHANS = 22;
|
|
|
|
const int VAL_INDEX_MISSING_ROWS = 23;
|
|
|
|
const int VAL_INDEX_ORPHAN_CHILD = 24;
|
2007-02-14 09:57:34 +01:00
|
|
|
const int VAL_INDEX_CYCLE = 25;
|
|
|
|
const int VAL_MAX_ERROR = 26;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2006-07-10 05:12:10 +02:00
|
|
|
#ifndef SUPERSERVER
|
|
|
|
struct DSqlCacheItem
|
|
|
|
{
|
|
|
|
Lock* lock;
|
|
|
|
bool locked;
|
|
|
|
bool obsolete;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// the attachment block; one is created for each attachment to a database
|
|
|
|
//
|
2004-03-18 06:56:06 +01:00
|
|
|
class Attachment : public pool_alloc<type_att>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2004-03-31 20:03:51 +02:00
|
|
|
explicit Attachment(Database* dbb) :
|
2004-03-14 14:34:43 +01:00
|
|
|
att_database(dbb),
|
2007-11-29 11:26:23 +01:00
|
|
|
att_stats(&dbb->dbb_stats),
|
2004-03-14 14:34:43 +01:00
|
|
|
att_lc_messages(*dbb->dbb_permanent),
|
|
|
|
att_working_directory(*dbb->dbb_permanent),
|
2004-11-22 21:22:03 +01:00
|
|
|
att_filename(*dbb->dbb_permanent),
|
2004-11-26 02:01:27 +01:00
|
|
|
att_context_vars(*dbb->dbb_permanent),
|
|
|
|
att_network_protocol(*dbb->dbb_permanent),
|
2007-05-16 09:54:33 +02:00
|
|
|
att_remote_address(*dbb->dbb_permanent),
|
|
|
|
att_remote_process(*dbb->dbb_permanent)
|
2006-07-10 05:12:10 +02:00
|
|
|
#ifndef SUPERSERVER
|
|
|
|
, att_dsql_cache(*dbb->dbb_permanent)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-06-15 11:28:56 +02:00
|
|
|
~Attachment();
|
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
/* Attachment()
|
2001-12-24 03:51:06 +01:00
|
|
|
: att_database(0),
|
|
|
|
att_next(0),
|
|
|
|
att_blocking(0),
|
|
|
|
att_user(0),
|
|
|
|
att_transactions(0),
|
|
|
|
att_dbkey_trans(0),
|
|
|
|
att_requests(0),
|
|
|
|
att_active_sorts(0),
|
|
|
|
att_id_lock(0),
|
|
|
|
att_attachment_id(0),
|
|
|
|
att_lock_owner_handle(0),
|
|
|
|
att_event_session(0),
|
|
|
|
att_security_class(0),
|
|
|
|
att_security_classes(0),
|
|
|
|
att_flags(0),
|
|
|
|
att_charset(0),
|
|
|
|
att_lc_messages(0),
|
|
|
|
att_long_locks(0),
|
|
|
|
att_compatibility_table(0),
|
|
|
|
att_val_errors(0),
|
|
|
|
att_working_directory(0)
|
|
|
|
{
|
|
|
|
att_counts[0] = 0;
|
2003-01-16 18:47:10 +01:00
|
|
|
}*/
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
Database* att_database; // Parent databasea block
|
|
|
|
Attachment* att_next; // Next attachment to database
|
|
|
|
Attachment* att_blocking; // Blocking attachment, if any
|
|
|
|
UserId* att_user; // User identification
|
|
|
|
jrd_tra* att_transactions; // Transactions belonging to attachment
|
|
|
|
jrd_tra* att_dbkey_trans; // transaction to control db-key scope
|
|
|
|
jrd_req* att_requests; // Requests belonging to attachment
|
|
|
|
sort_context* att_active_sorts; // Active sorts
|
|
|
|
Lock* att_id_lock; // Attachment lock (if any)
|
|
|
|
SLONG att_attachment_id; // Attachment ID
|
|
|
|
SLONG att_lock_owner_handle; // Handle for the lock manager
|
|
|
|
SLONG att_event_session; // Event session id, if any
|
|
|
|
SecurityClass* att_security_class; // security class for database
|
2004-03-28 11:10:30 +02:00
|
|
|
SecurityClass* att_security_classes; // security classes
|
|
|
|
vcl* att_counts[DBB_max_count];
|
2006-10-07 12:53:01 +02:00
|
|
|
RuntimeStatistics att_stats;
|
2006-07-21 03:35:17 +02:00
|
|
|
ULONG att_flags; // Flags describing the state of the attachment
|
|
|
|
SSHORT att_charset; // user's charset specified in dpb
|
2006-02-23 06:08:26 +01:00
|
|
|
// The following data member is set but never used, so the DPB to set the location of a
|
|
|
|
// customized firebird.msg file doesn't work; the only way is to use an env var.
|
2004-11-25 17:09:12 +01:00
|
|
|
Firebird::PathName att_lc_messages; // attachment's preference for message natural language
|
2006-07-21 03:35:17 +02:00
|
|
|
Lock* att_long_locks; // outstanding two phased locks
|
2005-12-02 08:35:34 +01:00
|
|
|
vec<Lock*>* att_compatibility_table; // hash table of compatible locks
|
2004-03-28 11:10:30 +02:00
|
|
|
vcl* att_val_errors;
|
2004-03-14 14:34:43 +01:00
|
|
|
Firebird::PathName att_working_directory; // Current working directory is cached
|
|
|
|
Firebird::PathName att_filename; // alias used to attach the database
|
2006-07-21 03:35:17 +02:00
|
|
|
Firebird::TimeStamp att_timestamp; // Connection date and time
|
|
|
|
Firebird::StringMap att_context_vars; // Context variables for the connection
|
|
|
|
Firebird::string att_network_protocol; // Network protocol used by client for connection
|
|
|
|
Firebird::string att_remote_address; // Protocol-specific addess of remote client
|
2006-09-14 15:47:31 +02:00
|
|
|
SLONG att_remote_pid; // Process id of remote client
|
2007-05-16 09:54:33 +02:00
|
|
|
Firebird::PathName att_remote_process; // Process name of remote client
|
2007-10-28 15:54:16 +01:00
|
|
|
RandomGenerator att_random_generator; // Random bytes generator
|
2006-07-12 17:13:22 +02:00
|
|
|
#ifndef SUPERSERVER
|
2006-07-21 03:35:17 +02:00
|
|
|
Lock* att_temp_pg_lock; // temporary pagespace ID lock
|
2006-07-12 17:13:22 +02:00
|
|
|
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
|
2007-07-25 15:21:59 +02:00
|
|
|
Firebird::string, DSqlCacheItem> > > att_dsql_cache; // DSQL cache locks
|
2006-07-12 17:13:22 +02:00
|
|
|
#endif
|
2006-08-16 17:15:58 +02:00
|
|
|
|
|
|
|
bool locksmith() const;
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Attachment flags
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_no_cleanup = 1; // Don't expunge, purge, or garbage collect
|
|
|
|
const ULONG ATT_shutdown = 2; // attachment has been shutdown
|
2006-02-23 06:08:26 +01:00
|
|
|
//const ULONG ATT_shutdown_notify = 4; // attachment has notified client of shutdown
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_shutdown_manager = 8; // attachment requesting shutdown
|
|
|
|
const ULONG ATT_lck_init_done = 16; // LCK_init() called for the attachment
|
|
|
|
const ULONG ATT_exclusive = 32; // attachment wants exclusive database access
|
|
|
|
const ULONG ATT_attach_pending = 64; // Indicate attachment is only pending
|
|
|
|
const ULONG ATT_exclusive_pending = 128; // Indicate exclusive attachment pending
|
|
|
|
const ULONG ATT_gbak_attachment = 256; // Indicate GBAK attachment
|
2006-02-23 06:08:26 +01:00
|
|
|
#ifdef GOVERNOR
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_security_db = 512; // Indicates an implicit attachment to the security db
|
2006-02-23 06:08:26 +01:00
|
|
|
#endif
|
2007-04-09 18:15:29 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#ifdef GARBAGE_THREAD
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_notify_gc = 1024; // Notify garbage collector to expunge, purge ..
|
|
|
|
const ULONG ATT_disable_notify_gc = 2048; // Temporarily perform own garbage collection
|
|
|
|
const ULONG ATT_garbage_collector = 4096; // I'm a garbage collector
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_NO_CLEANUP = (ATT_no_cleanup | ATT_notify_gc);
|
2001-05-23 15:26:42 +02:00
|
|
|
#else
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_NO_CLEANUP = ATT_no_cleanup;
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
const ULONG ATT_cancel_raise = 8192; // Cancel currently running operation
|
|
|
|
const ULONG ATT_cancel_disable = 16384; // Disable cancel operations
|
|
|
|
const ULONG ATT_gfix_attachment = 32768; // Indicate a GFIX attachment
|
|
|
|
const ULONG ATT_gstat_attachment = 65536; // Indicate a GSTAT attachment
|
2006-11-05 19:30:36 +01:00
|
|
|
const ULONG ATT_no_db_triggers = 131072; // Don't execute database triggers
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Procedure block
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
class jrd_prc : public pool_alloc<type_prc>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
2006-07-21 03:35:17 +02:00
|
|
|
public:
|
2004-04-10 21:03:42 +02:00
|
|
|
USHORT prc_id;
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT prc_flags;
|
|
|
|
USHORT prc_inputs;
|
2004-01-16 13:59:16 +01:00
|
|
|
USHORT prc_defaults;
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT prc_outputs;
|
2006-07-21 03:35:17 +02:00
|
|
|
jrd_nod* prc_input_msg; // It's set once by met.epp and never used.
|
2004-03-11 06:04:26 +01:00
|
|
|
jrd_nod* prc_output_msg;
|
2004-03-30 06:10:52 +02:00
|
|
|
Format* prc_input_fmt;
|
|
|
|
Format* prc_output_fmt;
|
|
|
|
Format* prc_format;
|
2006-07-21 03:35:17 +02:00
|
|
|
vec<Parameter*>* prc_input_fields; // vector of field blocks
|
|
|
|
vec<Parameter*>* prc_output_fields; // vector of field blocks
|
|
|
|
prc_t prc_type; // procedure type
|
|
|
|
jrd_req* prc_request; // compiled procedure request
|
|
|
|
USHORT prc_use_count; // requests compiled with procedure
|
|
|
|
SSHORT prc_int_use_count; // number of procedures compiled with procedure, set and
|
|
|
|
// used internally in the MET_clear_cache procedure
|
|
|
|
// no code should rely on value of this field
|
|
|
|
// (it will usually be 0)
|
|
|
|
Lock* prc_existence_lock; // existence lock, if any
|
|
|
|
Firebird::MetaName prc_security_name; // security class name for procedure
|
|
|
|
Firebird::MetaName prc_name; // ascic name
|
2006-12-14 17:11:21 +01:00
|
|
|
USHORT prc_alter_count; // No. of times the procedure was altered
|
2004-03-20 15:57:40 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
public:
|
2004-03-31 20:03:51 +02:00
|
|
|
explicit jrd_prc(MemoryPool& p) : prc_security_name(p), prc_name(p) {}
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
// prc_flags
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT PRC_scanned = 1; // Field expressions scanned
|
2006-02-23 06:08:26 +01:00
|
|
|
const USHORT PRC_system = 2; // Set in met.epp, never tested.
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT PRC_obsolete = 4; // Procedure known gonzo
|
|
|
|
const USHORT PRC_being_scanned = 8; // New procedure needs dependencies during scan
|
2006-02-23 06:08:26 +01:00
|
|
|
//const USHORT PRC_blocking = 16; // Blocking someone from dropping procedure
|
|
|
|
const USHORT PRC_create = 32; // Newly created. Set in met.epp, never tested or disabled.
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT PRC_being_altered = 64; // Procedure is getting altered
|
2004-04-10 21:46:48 +02:00
|
|
|
// This flag is used to make sure that MET_remove_procedure
|
|
|
|
// does not delete and remove procedure block from cache
|
|
|
|
// so dfw.epp:modify_procedure() can flip procedure body without
|
|
|
|
// invalidating procedure pointers from other parts of metadata cache
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT PRC_check_existence = 128; // Existence lock released
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-12-14 17:11:21 +01:00
|
|
|
const USHORT MAX_PROC_ALTER = 64; // No. of times an in-cache procedure can be altered
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Parameter block
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
class Parameter : public pool_alloc<type_prm>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
2005-12-02 08:35:34 +01:00
|
|
|
public:
|
2005-05-12 20:28:04 +02:00
|
|
|
USHORT prm_number;
|
2004-03-28 11:10:30 +02:00
|
|
|
dsc prm_desc;
|
2005-12-02 08:35:34 +01:00
|
|
|
jrd_nod* prm_default_value;
|
2006-07-21 03:35:17 +02:00
|
|
|
Firebird::MetaName prm_name; // asciiz name
|
2005-12-02 08:35:34 +01:00
|
|
|
//public:
|
2005-05-12 20:28:04 +02:00
|
|
|
explicit Parameter(MemoryPool& p) : prm_name(p) { }
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Index block to cache index information
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-19 07:14:53 +01:00
|
|
|
class IndexBlock : public pool_alloc<type_idb>
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2005-12-02 08:35:34 +01:00
|
|
|
public:
|
2004-03-19 07:14:53 +01:00
|
|
|
IndexBlock* idb_next;
|
2006-07-21 03:35:17 +02:00
|
|
|
jrd_nod* idb_expression; // node tree for index expression
|
|
|
|
jrd_req* idb_expression_request; // request in which index expression is evaluated
|
|
|
|
dsc idb_expression_desc; // descriptor for expression result
|
|
|
|
Lock* idb_lock; // lock to synchronize changes to index
|
2006-02-23 06:08:26 +01:00
|
|
|
USHORT idb_id;
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2004-03-19 07:14:53 +01:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// general purpose vector
|
2001-12-24 03:51:06 +01:00
|
|
|
template <class T, USHORT TYPE = type_vec>
|
|
|
|
class vec_base : protected pool_alloc<TYPE>
|
|
|
|
{
|
|
|
|
public:
|
2006-04-25 19:49:24 +02:00
|
|
|
typedef typename Firebird::Array<T>::iterator iterator;
|
|
|
|
typedef typename Firebird::Array<T>::const_iterator const_iterator;
|
2005-12-02 08:35:34 +01:00
|
|
|
/*
|
2001-12-24 03:51:06 +01:00
|
|
|
static vec_base* newVector(MemoryPool& p, int len)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
return FB_NEW(p) vec_base<T, TYPE>(p, len);
|
|
|
|
}
|
2001-12-24 03:51:06 +01:00
|
|
|
static vec_base* newVector(MemoryPool& p, const vec_base& base)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
return FB_NEW(p) vec_base<T, TYPE>(p, base);
|
|
|
|
}
|
2005-12-02 08:35:34 +01:00
|
|
|
*/
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2004-03-28 11:10:30 +02:00
|
|
|
// CVC: This should be size_t instead of ULONG for maximum portability.
|
2006-04-25 19:49:24 +02:00
|
|
|
ULONG count() const { return v.getCount(); }
|
|
|
|
T& operator[](size_t index) { return v[index]; }
|
|
|
|
const T& operator[](size_t index) const { return v[index]; }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
iterator begin() { return v.begin(); }
|
|
|
|
iterator end() { return v.end(); }
|
2005-01-25 07:40:00 +01:00
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
const_iterator begin() const { return v.begin(); }
|
|
|
|
const_iterator end() const { return v.end(); }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
void clear() { v.clear(); }
|
|
|
|
//void prepend(int n) { v.insert(v.begin(), n); }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
// T* memPtr() { return &*(v.begin()); }
|
|
|
|
T* memPtr() { return &v[0]; }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2006-04-25 19:49:24 +02:00
|
|
|
void resize(size_t n, T val = T()) { v.resize(n, val); }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
2003-12-22 11:00:59 +01:00
|
|
|
void operator delete(void* mem) { MemoryPool::globalFree(mem); }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
protected:
|
|
|
|
vec_base(MemoryPool& p, int len)
|
2006-04-25 19:49:24 +02:00
|
|
|
: v(p, len) { v.resize(len); }
|
2001-12-24 03:51:06 +01:00
|
|
|
vec_base(MemoryPool& p, const vec_base& base)
|
2006-04-25 19:49:24 +02:00
|
|
|
: v(p) { v = base.v; }
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
private:
|
2006-04-25 19:49:24 +02:00
|
|
|
Firebird::Array<T> v;
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-12-02 08:35:34 +01:00
|
|
|
template <typename T>
|
|
|
|
class vec : public vec_base<T, type_vec>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
|
|
|
public:
|
2006-07-21 03:35:17 +02:00
|
|
|
static vec* newVector(MemoryPool& p, int len)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2005-12-02 08:35:34 +01:00
|
|
|
return FB_NEW(p) vec<T>(p, len);
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2006-07-21 03:35:17 +02:00
|
|
|
static vec* newVector(MemoryPool& p, const vec& base)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2005-12-02 08:35:34 +01:00
|
|
|
return FB_NEW(p) vec<T>(p, base);
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2003-02-19 16:25:27 +01:00
|
|
|
static vec* newVector(MemoryPool& p, vec* base, int len)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
if (!base)
|
2005-12-02 08:35:34 +01:00
|
|
|
base = FB_NEW(p) vec<T>(p, len);
|
2004-02-20 07:43:27 +01:00
|
|
|
else if (len > (int) base->count())
|
|
|
|
base->resize(len);
|
|
|
|
return base;
|
|
|
|
}
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
private:
|
2006-07-21 03:35:17 +02:00
|
|
|
vec(MemoryPool& p, int len) : vec_base<T, type_vec>(p, len) {}
|
|
|
|
vec(MemoryPool& p, const vec& base) : vec_base<T, type_vec>(p, base) {}
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
class vcl : public vec_base<SLONG, type_vcl>
|
|
|
|
{
|
|
|
|
public:
|
2006-07-21 03:35:17 +02:00
|
|
|
static vcl* newVector(MemoryPool& p, int len)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
return FB_NEW(p) vcl(p, len);
|
|
|
|
}
|
2006-07-21 03:35:17 +02:00
|
|
|
static vcl* newVector(MemoryPool& p, const vcl& base)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
return FB_NEW(p) vcl(p, base);
|
|
|
|
}
|
2003-02-19 16:25:27 +01:00
|
|
|
static vcl* newVector(MemoryPool& p, vcl* base, int len)
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
if (!base)
|
|
|
|
base = FB_NEW(p) vcl(p, len);
|
|
|
|
else if (len > (int) base->count())
|
|
|
|
base->resize(len);
|
|
|
|
return base;
|
|
|
|
}
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
private:
|
2006-07-21 03:35:17 +02:00
|
|
|
vcl(MemoryPool& p, int len) : vec_base<SLONG, type_vcl>(p, len) {}
|
|
|
|
vcl(MemoryPool& p, const vcl& base) : vec_base<SLONG, type_vcl>(p, base) {}
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2005-12-02 08:35:34 +01:00
|
|
|
//#define TEST_VECTOR(vector, number) ((vector && number < vector->count()) ?
|
|
|
|
// (*vector)[number] : NULL)
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2001-12-24 03:51:06 +01:00
|
|
|
//
|
|
|
|
// Transaction element block
|
|
|
|
//
|
2004-05-24 19:31:47 +02:00
|
|
|
struct teb {
|
2004-03-18 06:56:06 +01:00
|
|
|
Attachment** teb_database;
|
2001-05-23 15:26:42 +02:00
|
|
|
int teb_tpb_length;
|
2004-02-20 07:43:27 +01:00
|
|
|
UCHAR* teb_tpb;
|
2004-05-24 19:31:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef teb TEB;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Blocking Thread Block
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-18 06:56:06 +01:00
|
|
|
class BlockingThread : public pool_alloc<type_btb>
|
2001-12-24 03:51:06 +01:00
|
|
|
{
|
2006-07-21 03:35:17 +02:00
|
|
|
public:
|
2004-03-18 06:56:06 +01:00
|
|
|
BlockingThread* btb_next;
|
2004-04-20 07:57:31 +02:00
|
|
|
thread* btb_thread_id;
|
2001-12-24 03:51:06 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Window block for loading cached pages into
|
2003-12-11 11:33:30 +01:00
|
|
|
// CVC: Apparently, the only possible values are HEADER_PAGE==0 and LOG_PAGE==2
|
|
|
|
// and reside in ods.h, although I watched a place with 1 and others with members
|
|
|
|
// of a struct.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 19:31:47 +02:00
|
|
|
struct win {
|
2006-05-22 00:07:35 +02:00
|
|
|
PageNumber win_page;
|
2004-03-20 15:57:40 +01:00
|
|
|
Ods::pag* win_buffer;
|
2004-03-28 11:10:30 +02:00
|
|
|
exp_index_buf* win_expanded_buffer;
|
2004-03-18 06:56:06 +01:00
|
|
|
class BufferDesc* win_bdb;
|
2001-05-23 15:26:42 +02:00
|
|
|
SSHORT win_scans;
|
|
|
|
USHORT win_flags;
|
2006-05-22 00:07:35 +02:00
|
|
|
// explicit win(SLONG wp) : win_page(wp), win_flags(0) {}
|
|
|
|
explicit win(const PageNumber& wp) : win_page(wp), win_flags(0) {}
|
|
|
|
win(const USHORT pageSpaceID, const SLONG pageNum) :
|
|
|
|
win_page(pageSpaceID, pageNum), win_flags(0) {}
|
2004-05-24 19:31:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef win WIN;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-12-11 11:33:30 +01:00
|
|
|
// This is a compilation artifact: I wanted to be sure I would pick all old "win"
|
|
|
|
// declarations at the top, so "win" was built with a mandatory argument in
|
|
|
|
// the constructor. This struct satisfies a single place with an array. The
|
|
|
|
// alternative would be to initialize 16 elements of the array with 16 calls
|
|
|
|
// to the constructor: win my_array[n] = {win(-1), ... (win-1)};
|
|
|
|
// When all places are changed, this class can disappear and win's constructor
|
|
|
|
// may get the default value of -1 to "wp".
|
|
|
|
struct win_for_array: public win
|
|
|
|
{
|
2006-05-22 00:07:35 +02:00
|
|
|
win_for_array() : win(DB_PAGE_SPACE, -1) {}
|
2003-12-11 11:33:30 +01:00
|
|
|
};
|
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
// win_flags
|
2003-12-11 11:33:30 +01:00
|
|
|
|
2006-07-22 05:54:43 +02:00
|
|
|
const USHORT WIN_large_scan = 1; // large sequential scan
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT WIN_secondary = 2; // secondary stream
|
|
|
|
const USHORT WIN_garbage_collector = 4; // garbage collector's window
|
|
|
|
const USHORT WIN_garbage_collect = 8; // scan left a page for garbage collector
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
// Thread specific database block
|
2004-08-30 20:11:08 +02:00
|
|
|
class thread_db : public ThreadData
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
2004-08-16 14:28:43 +02:00
|
|
|
private:
|
|
|
|
JrdMemoryPool* tdbb_default;
|
2004-08-30 20:11:08 +02:00
|
|
|
void setDefaultPool(JrdMemoryPool* p)
|
|
|
|
{
|
|
|
|
tdbb_default = p;
|
|
|
|
}
|
|
|
|
friend class Firebird::SubsystemContextPoolHolder <Jrd::thread_db, JrdMemoryPool>;
|
2004-06-08 15:41:08 +02:00
|
|
|
public:
|
2004-08-30 20:11:08 +02:00
|
|
|
thread_db()
|
|
|
|
: ThreadData(ThreadData::tddDBB)
|
|
|
|
{
|
|
|
|
tdbb_default = 0;
|
|
|
|
tdbb_database = 0;
|
|
|
|
tdbb_attachment = 0;
|
|
|
|
tdbb_transaction = 0;
|
|
|
|
tdbb_request = 0;
|
|
|
|
tdbb_status_vector = 0;
|
|
|
|
tdbb_quantum = 0;
|
|
|
|
tdbb_flags = 0;
|
2006-05-22 00:07:35 +02:00
|
|
|
tdbb_temp_attid = tdbb_temp_traid = 0;
|
2004-08-30 20:11:08 +02:00
|
|
|
JRD_inuse_clear(this);
|
|
|
|
}
|
2004-03-07 08:58:55 +01:00
|
|
|
Database* tdbb_database;
|
2004-06-08 15:41:08 +02:00
|
|
|
Attachment* tdbb_attachment;
|
2004-02-20 07:43:27 +01:00
|
|
|
jrd_tra* tdbb_transaction;
|
|
|
|
jrd_req* tdbb_request;
|
2003-04-10 08:49:16 +02:00
|
|
|
ISC_STATUS* tdbb_status_vector;
|
2004-03-20 15:57:40 +01:00
|
|
|
SSHORT tdbb_quantum; // Cycles remaining until voluntary schedule
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT tdbb_flags;
|
|
|
|
struct iuo tdbb_mutexes;
|
2002-07-29 17:37:59 +02:00
|
|
|
|
2006-05-22 00:07:35 +02:00
|
|
|
SLONG tdbb_temp_attid; // current temporary table scope
|
|
|
|
SLONG tdbb_temp_traid; // current temporary table scope
|
|
|
|
|
2003-10-03 12:14:05 +02:00
|
|
|
#if defined(UNIX) && defined(SUPERSERVER)
|
2006-07-21 03:35:17 +02:00
|
|
|
sigjmp_buf tdbb_sigsetjmp;
|
2003-10-29 07:07:22 +01:00
|
|
|
#endif
|
2004-08-16 14:28:43 +02:00
|
|
|
|
|
|
|
JrdMemoryPool* getDefaultPool()
|
|
|
|
{
|
|
|
|
return tdbb_default;
|
|
|
|
}
|
2004-03-11 06:04:26 +01:00
|
|
|
};
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-04 00:42:47 +02:00
|
|
|
// tdbb_flags
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
const USHORT TDBB_sweeper = 1; // Thread sweeper or garbage collector
|
|
|
|
const USHORT TDBB_no_cache_unwind = 2; // Don't unwind page buffer cache
|
|
|
|
const USHORT TDBB_prc_being_dropped = 4; // Dropping a procedure
|
2007-04-24 16:05:46 +02:00
|
|
|
const USHORT TDBB_backup_write_locked = 8; // BackupManager has write lock on LCK_backup_database
|
2007-05-02 08:57:18 +02:00
|
|
|
const USHORT TDBB_stack_trace_done = 16; // PSQL stack trace is added into status-vector
|
|
|
|
const USHORT TDBB_shutdown_manager = 32; // Server shutdown thread
|
|
|
|
const USHORT TDBB_deferred = 64; // deferred work performed now
|
|
|
|
const USHORT TDBB_sys_error = 128; // error shouldn't be handled by the looper
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-09 07:48:33 +02:00
|
|
|
// duplicate context of firebird string to store in jrd_nod::nod_arg
|
2004-03-31 20:03:51 +02:00
|
|
|
inline char* stringDup(MemoryPool& p, const Firebird::string& s)
|
|
|
|
{
|
|
|
|
char* rc = (char*) p.allocate(s.length() + 1, 0
|
2004-04-18 16:22:27 +02:00
|
|
|
#ifdef DEBUG_GDS_ALLOC
|
2004-03-31 20:03:51 +02:00
|
|
|
, __FILE__, __LINE__
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
strcpy(rc, s.c_str());
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2004-05-09 07:48:33 +02:00
|
|
|
inline char* stringDup(MemoryPool& p, const char* s, size_t l)
|
2004-04-18 16:22:27 +02:00
|
|
|
{
|
|
|
|
char* rc = (char*) p.allocate(l + 1, 0
|
|
|
|
#ifdef DEBUG_GDS_ALLOC
|
|
|
|
, __FILE__, __LINE__
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
memcpy(rc, s, l);
|
|
|
|
rc[l] = 0;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2004-05-26 18:12:05 +02:00
|
|
|
inline char* stringDup(MemoryPool& p, const char* s)
|
|
|
|
{
|
|
|
|
if (! s)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return stringDup(p, s, strlen(s));
|
|
|
|
}
|
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
// Used in string convsersion calls
|
|
|
|
typedef Firebird::HalfStaticArray<UCHAR, 256> MoveBuffer;
|
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
} //namespace Jrd
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Lock levels
|
2004-05-03 19:36:27 +02:00
|
|
|
#include "../lock/lock.h"
|
2004-03-20 15:57:40 +01:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Random string block -- as long as impure areas don't have
|
|
|
|
// constructors and destructors, the need this varying string
|
2004-03-20 15:57:40 +01:00
|
|
|
|
2005-05-12 20:28:04 +02:00
|
|
|
class VaryingString : public pool_alloc_rpt<SCHAR, type_str>
|
2004-03-20 15:57:40 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
USHORT str_length;
|
2005-05-12 20:28:04 +02:00
|
|
|
UCHAR str_data[2]; // one byte for ALLOC and one for the NULL
|
2004-03-20 15:57:40 +01:00
|
|
|
};
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// Threading macros
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-19 20:14:29 +02:00
|
|
|
/* Define JRD_get_thread_data off the platform specific version.
|
2001-05-23 15:26:42 +02:00
|
|
|
* If we're in DEV mode, also do consistancy checks on the
|
|
|
|
* retrieved memory structure. This was originally done to
|
|
|
|
* track down cases of no "PUT_THREAD_DATA" on the NLM.
|
|
|
|
*
|
|
|
|
* This allows for NULL thread data (which might be an error by itself)
|
|
|
|
* If there is thread data,
|
2004-03-11 06:04:26 +01:00
|
|
|
* AND it is tagged as being a thread_db.
|
2001-05-23 15:26:42 +02:00
|
|
|
* AND it has a non-NULL tdbb_database field,
|
|
|
|
* THEN we validate that the structure there is a database block.
|
|
|
|
* Otherwise, we return what we got.
|
|
|
|
* We can't always validate the database field, as during initialization
|
|
|
|
* there is no tdbb_database set up.
|
|
|
|
*/
|
2004-05-22 16:28:54 +02:00
|
|
|
|
2004-06-08 15:41:08 +02:00
|
|
|
#include "../jrd/thd.h"
|
2004-05-22 16:28:54 +02:00
|
|
|
|
2006-08-16 17:15:58 +02:00
|
|
|
#if defined(DEV_BUILD)
|
2004-05-22 16:28:54 +02:00
|
|
|
#include "../jrd/err_proto.h"
|
|
|
|
|
2004-05-23 05:18:10 +02:00
|
|
|
inline Jrd::thread_db* JRD_get_thread_data() {
|
2004-08-30 20:11:08 +02:00
|
|
|
ThreadData* p1 = ThreadData::getSpecific();
|
|
|
|
if (p1 && p1->getType() == ThreadData::tddDBB)
|
2004-05-22 16:28:54 +02:00
|
|
|
{
|
|
|
|
Jrd::thread_db* p2 = (Jrd::thread_db*)p1;
|
|
|
|
if (p2->tdbb_database && MemoryPool::blk_type(p2->tdbb_database) != type_dbb)
|
|
|
|
{
|
|
|
|
BUGCHECK(147);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (Jrd::thread_db*) p1;
|
|
|
|
}
|
2004-05-23 05:18:10 +02:00
|
|
|
inline void CHECK_TDBB(const Jrd::thread_db* tdbb) {
|
2004-08-30 20:11:08 +02:00
|
|
|
fb_assert(tdbb && (tdbb->getType() == ThreadData::tddDBB) &&
|
2004-05-23 05:18:10 +02:00
|
|
|
(!tdbb->tdbb_database ||
|
|
|
|
MemoryPool::blk_type(tdbb->tdbb_database) == type_dbb));
|
|
|
|
}
|
|
|
|
inline void CHECK_DBB(const Jrd::Database* dbb) {
|
|
|
|
fb_assert(dbb && MemoryPool::blk_type(dbb) == type_dbb);
|
|
|
|
}
|
2004-05-22 16:28:54 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#else
|
2006-07-21 03:35:17 +02:00
|
|
|
// PROD_BUILD
|
2004-05-23 05:18:10 +02:00
|
|
|
inline Jrd::thread_db* JRD_get_thread_data() {
|
2004-08-30 20:11:08 +02:00
|
|
|
return (Jrd::thread_db*) ThreadData::getSpecific();
|
2004-05-22 16:28:54 +02:00
|
|
|
}
|
2004-05-26 06:53:05 +02:00
|
|
|
inline void CHECK_DBB(const Jrd::Database* dbb) {
|
2004-05-23 05:18:10 +02:00
|
|
|
}
|
|
|
|
inline void CHECK_TDBB(const Jrd::thread_db* tdbb) {
|
|
|
|
}
|
2004-05-22 16:28:54 +02:00
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2004-05-23 05:18:10 +02:00
|
|
|
inline Jrd::Database* GET_DBB() {
|
|
|
|
return JRD_get_thread_data()->tdbb_database;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*
|
2004-03-11 06:04:26 +01:00
|
|
|
* macros used to set thread_db and Database pointers when there are not set already *
|
2001-05-23 15:26:42 +02:00
|
|
|
*-------------------------------------------------------------------------*/
|
2004-05-23 05:18:10 +02:00
|
|
|
inline void SET_TDBB(Jrd::thread_db* &tdbb) {
|
|
|
|
if (tdbb == NULL) {
|
|
|
|
tdbb = JRD_get_thread_data();
|
|
|
|
}
|
|
|
|
CHECK_TDBB(tdbb);
|
|
|
|
}
|
2004-05-24 19:31:47 +02:00
|
|
|
inline void SET_DBB(Jrd::Database* &dbb) {
|
2004-05-23 05:18:10 +02:00
|
|
|
if (dbb == NULL) {
|
|
|
|
dbb = GET_DBB();
|
|
|
|
}
|
|
|
|
CHECK_DBB(dbb);
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-05-01 06:12:30 +02:00
|
|
|
#ifdef MULTI_THREAD
|
2006-04-30 20:15:30 +02:00
|
|
|
#define THD_JRD_MUTEX_LOCK(mutx) JRD_mutex_lock(mutx)
|
|
|
|
#define THD_JRD_MUTEX_UNLOCK(mutx) JRD_mutex_unlock(mutx)
|
2001-05-23 15:26:42 +02:00
|
|
|
#else
|
|
|
|
#define THD_JRD_MUTEX_LOCK(mutx)
|
|
|
|
#define THD_JRD_MUTEX_UNLOCK(mutx)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
// global variables for engine
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
#if !defined(REQUESTER)
|
|
|
|
|
|
|
|
extern int debug;
|
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
#endif // REQUESTER
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2004-05-21 08:16:17 +02:00
|
|
|
/* Define the xxx_thread_data macros. These are needed in the whole
|
|
|
|
component, but they are defined differently for use in jrd.cpp (JRD_MAIN)
|
2001-05-23 15:26:42 +02:00
|
|
|
Here we have a function which sets some flags, and then calls THD_put_specific
|
|
|
|
so in this case we define the macro as calling that function. */
|
2004-05-21 08:16:17 +02:00
|
|
|
// CVC: This may be obsolete now that different subsystems use different macro/function names.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 03:03:41 +02:00
|
|
|
inline static void JRD_set_thread_data(Jrd::thread_db* &tdbb, Jrd::thread_db& thd_context)
|
|
|
|
{
|
|
|
|
tdbb = &thd_context;
|
2004-06-08 15:41:08 +02:00
|
|
|
tdbb->putSpecific();
|
2004-05-24 03:03:41 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-26 06:53:05 +02:00
|
|
|
inline void JRD_restore_thread_data() {
|
2004-08-30 20:11:08 +02:00
|
|
|
ThreadData::restoreSpecific();
|
2004-05-23 05:18:10 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-08-30 20:11:08 +02:00
|
|
|
namespace Jrd {
|
|
|
|
typedef Firebird::SubsystemContextPoolHolder <Jrd::thread_db, JrdMemoryPool>
|
|
|
|
ContextPoolHolder;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-07-21 03:35:17 +02:00
|
|
|
#endif // JRD_JRD_H
|