| 247 | const ULONG DBB_shutdown_single = 0x100L; // Database is in single-user maintenance mode |
| 248 | |
| 249 | class Database : public pool_alloc<type_dbb> |
| 250 | { |
| 251 | // This class is a reference-counted container for all "global" |
| 252 | // (shared among different dbb's) objects -- e.g. the lock manager. |
| 253 | // The contained objects are created on demand (upon the first reference). |
| 254 | // The container is destroyed by the last dbb going away and |
| 255 | // it automatically destroys all the objects it holds. |
| 256 | |
| 257 | class GlobalObjectHolder : public Firebird::RefCounted, public Firebird::GlobalStorage |
| 258 | { |
| 259 | struct DbId; |
| 260 | typedef Firebird::HashTable<DbId, Firebird::DEFAULT_HASH_SIZE, |
| 261 | Firebird::string, DbId, DbId > DbIdHash; |
| 262 | |
| 263 | struct DbId : public DbIdHash::Entry, public Firebird::GlobalStorage, public Firebird::RefCounted |
| 264 | { |
| 265 | DbId(const Firebird::string& x, GlobalObjectHolder* h) |
| 266 | : id(getPool(), x), holder(h) |
| 267 | {} |
| 268 | |
| 269 | DbId* get() |
| 270 | { |
| 271 | return this; |
| 272 | } |
| 273 | |
| 274 | bool isEqual(const Firebird::string& val) const |
| 275 | { |
| 276 | return val == id; |
| 277 | } |
| 278 | |
| 279 | static const Firebird::string& generate(const DbId& item) |
| 280 | { |
| 281 | return item.id; |
| 282 | } |
| 283 | |
| 284 | static FB_SIZE_T hash(const Firebird::string& value, FB_SIZE_T hashSize) |
| 285 | { |
| 286 | return Firebird::InternalHash::hash(value.length(), |
| 287 | (const UCHAR*) value.c_str(), |
| 288 | hashSize); |
| 289 | } |
| 290 | |
| 291 | const Firebird::string id; |
| 292 | GlobalObjectHolder* holder; |
| 293 | // This mutex is working very tight with `g_mutex`, so use it carefully to avoid possible deadlocks. |
| 294 | Firebird::Mutex shutdownMutex; |
| 295 | }; |
| 296 | |
| 297 | static Firebird::GlobalPtr<DbIdHash> g_hashTable; |
| 298 | static Firebird::GlobalPtr<Firebird::Mutex> g_mutex; |
| 299 | |
| 300 | public: |
| 301 | static GlobalObjectHolder* init(const Firebird::string& id, |
| 302 | const Firebird::PathName& filename, |
| 303 | Firebird::RefPtr<const Firebird::Config> config); |
| 304 | |
| 305 | int release() const override; |
| 306 | |