1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13#include "db_cxx.h" 14#include "dbinc/cxx_int.h" 15 16#include "dbinc/db_page.h" 17#include "dbinc/db_am.h" 18#include "dbinc/log.h" 19#include "dbinc_auto/common_ext.h" 20#include "dbinc_auto/log_ext.h" 21 22#ifdef HAVE_CXX_STDHEADERS 23using std::cerr; 24#endif 25 26// Helper macros for simple methods that pass through to the 27// underlying C method. They may return an error or raise an exception. 28// These macros expect that input _argspec is an argument 29// list element (e.g., "char *arg") and that _arglist is the arguments 30// that should be passed through to the C method (e.g., "(dbenv, arg)") 31// 32#define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \ 33int DbEnv::_name _argspec \ 34{ \ 35 DB_ENV *dbenv = unwrap(this); \ 36 int ret; \ 37 \ 38 if ((ret = dbenv->_name _arglist) != 0) { \ 39 _on_err; \ 40 } \ 41 return (ret); \ 42} 43 44#define DBENV_METHOD(_name, _argspec, _arglist) \ 45 DBENV_METHOD_ERR(_name, _argspec, _arglist, \ 46 DB_ERROR(this, "DbEnv::" # _name, ret, error_policy())) 47 48#define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \ 49int DbEnv::_name _argspec \ 50{ \ 51 DB_ENV *dbenv = unwrap(this); \ 52 \ 53 return (dbenv->_name _arglist); \ 54} 55 56#define DBENV_METHOD_VOID(_name, _argspec, _arglist) \ 57void DbEnv::_name _argspec \ 58{ \ 59 DB_ENV *dbenv = unwrap(this); \ 60 \ 61 dbenv->_name _arglist; \ 62} 63 64// The reason for a static variable is that some structures 65// (like Dbts) have no connection to any Db or DbEnv, so when 66// errors occur in their methods, we must have some reasonable 67// way to determine whether to throw or return errors. 68// 69// This variable is taken from flags whenever a DbEnv is constructed. 70// Normally there is only one DbEnv per program, and even if not, 71// there is typically a single policy of throwing or returning. 72// 73static int last_known_error_policy = ON_ERROR_UNKNOWN; 74 75// These 'glue' function are declared as extern "C" so they will 76// be compatible with picky compilers that do not allow mixing 77// of function pointers to 'C' functions with function pointers 78// to C++ functions. 79// 80extern "C" 81void _feedback_intercept_c(DB_ENV *dbenv, int opcode, int pct) 82{ 83 DbEnv::_feedback_intercept(dbenv, opcode, pct); 84} 85 86extern "C" 87void _paniccall_intercept_c(DB_ENV *dbenv, int errval) 88{ 89 DbEnv::_paniccall_intercept(dbenv, errval); 90} 91 92extern "C" 93void _event_func_intercept_c(DB_ENV *dbenv, u_int32_t event, void *event_info) 94{ 95 DbEnv::_event_func_intercept(dbenv, event, event_info); 96} 97 98extern "C" 99void _stream_error_function_c(const DB_ENV *dbenv, 100 const char *prefix, const char *message) 101{ 102 DbEnv::_stream_error_function(dbenv, prefix, message); 103} 104 105extern "C" 106void _stream_message_function_c(const DB_ENV *dbenv, const char *message) 107{ 108 DbEnv::_stream_message_function(dbenv, message); 109} 110 111extern "C" 112int _app_dispatch_intercept_c(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, db_recops op) 113{ 114 return (DbEnv::_app_dispatch_intercept(dbenv, dbt, lsn, op)); 115} 116 117extern "C" 118int _rep_send_intercept_c(DB_ENV *dbenv, const DBT *cntrl, const DBT *data, 119 const DB_LSN *lsn, int id, u_int32_t flags) 120{ 121 return (DbEnv::_rep_send_intercept(dbenv, 122 cntrl, data, lsn, id, flags)); 123} 124 125extern "C" 126int _isalive_intercept_c( 127 DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags) 128{ 129 return (DbEnv::_isalive_intercept(dbenv, pid, thrid, flags)); 130} 131 132extern "C" 133void _thread_id_intercept_c(DB_ENV *dbenv, pid_t *pidp, db_threadid_t *thridp) 134{ 135 DbEnv::_thread_id_intercept(dbenv, pidp, thridp); 136} 137 138extern "C" 139char *_thread_id_string_intercept_c(DB_ENV *dbenv, pid_t pid, 140 db_threadid_t thrid, char *buf) 141{ 142 return (DbEnv::_thread_id_string_intercept(dbenv, pid, thrid, buf)); 143} 144 145void DbEnv::_feedback_intercept(DB_ENV *dbenv, int opcode, int pct) 146{ 147 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 148 if (cxxenv == 0) { 149 DB_ERROR(0, 150 "DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); 151 return; 152 } 153 if (cxxenv->feedback_callback_ == 0) { 154 DB_ERROR(DbEnv::get_DbEnv(dbenv), 155 "DbEnv::feedback_callback", EINVAL, cxxenv->error_policy()); 156 return; 157 } 158 (*cxxenv->feedback_callback_)(cxxenv, opcode, pct); 159} 160 161void DbEnv::_paniccall_intercept(DB_ENV *dbenv, int errval) 162{ 163 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 164 if (cxxenv == 0) { 165 DB_ERROR(0, 166 "DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN); 167 return; 168 } 169 if (cxxenv->paniccall_callback_ == 0) { 170 DB_ERROR(cxxenv, "DbEnv::paniccall_callback", EINVAL, 171 cxxenv->error_policy()); 172 return; 173 } 174 (*cxxenv->paniccall_callback_)(cxxenv, errval); 175} 176 177void DbEnv::_event_func_intercept( 178 DB_ENV *dbenv, u_int32_t event, void *event_info) 179{ 180 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 181 if (cxxenv == 0) { 182 DB_ERROR(0, 183 "DbEnv::event_func_callback", EINVAL, ON_ERROR_UNKNOWN); 184 return; 185 } 186 if (cxxenv->event_func_callback_ == 0) { 187 DB_ERROR(cxxenv, "DbEnv::event_func_callback", EINVAL, 188 cxxenv->error_policy()); 189 return; 190 } 191 (*cxxenv->event_func_callback_)(cxxenv, event, event_info); 192} 193 194int DbEnv::_app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, 195 db_recops op) 196{ 197 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 198 if (cxxenv == 0) { 199 DB_ERROR(DbEnv::get_DbEnv(dbenv), 200 "DbEnv::app_dispatch_callback", EINVAL, ON_ERROR_UNKNOWN); 201 return (EINVAL); 202 } 203 if (cxxenv->app_dispatch_callback_ == 0) { 204 DB_ERROR(DbEnv::get_DbEnv(dbenv), 205 "DbEnv::app_dispatch_callback", EINVAL, 206 cxxenv->error_policy()); 207 return (EINVAL); 208 } 209 Dbt *cxxdbt = (Dbt *)dbt; 210 DbLsn *cxxlsn = (DbLsn *)lsn; 211 return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op)); 212} 213 214int DbEnv::_isalive_intercept( 215 DB_ENV *dbenv, pid_t pid, db_threadid_t thrid, u_int32_t flags) 216{ 217 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 218 if (cxxenv == 0) { 219 DB_ERROR(DbEnv::get_DbEnv(dbenv), 220 "DbEnv::isalive_callback", EINVAL, ON_ERROR_UNKNOWN); 221 return (0); 222 } 223 return ((*cxxenv->isalive_callback_)(cxxenv, pid, thrid, flags)); 224} 225 226int DbEnv::_rep_send_intercept(DB_ENV *dbenv, const DBT *cntrl, const DBT *data, 227 const DB_LSN *lsn, int id, u_int32_t flags) 228{ 229 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 230 if (cxxenv == 0) { 231 DB_ERROR(DbEnv::get_DbEnv(dbenv), 232 "DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN); 233 return (EINVAL); 234 } 235 const Dbt *cxxcntrl = (const Dbt *)cntrl; 236 const DbLsn *cxxlsn = (const DbLsn *)lsn; 237 Dbt *cxxdata = (Dbt *)data; 238 return ((*cxxenv->rep_send_callback_)(cxxenv, 239 cxxcntrl, cxxdata, cxxlsn, id, flags)); 240} 241 242void DbEnv::_thread_id_intercept(DB_ENV *dbenv, 243 pid_t *pidp, db_threadid_t *thridp) 244{ 245 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 246 if (cxxenv == 0) { 247 DB_ERROR(DbEnv::get_DbEnv(dbenv), 248 "DbEnv::thread_id_callback", EINVAL, ON_ERROR_UNKNOWN); 249 } else 250 cxxenv->thread_id_callback_(cxxenv, pidp, thridp); 251} 252 253char *DbEnv::_thread_id_string_intercept(DB_ENV *dbenv, 254 pid_t pid, db_threadid_t thrid, char *buf) 255{ 256 DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); 257 if (cxxenv == 0) { 258 DB_ERROR(DbEnv::get_DbEnv(dbenv), 259 "DbEnv::thread_id_string_callback", EINVAL, 260 ON_ERROR_UNKNOWN); 261 return (NULL); 262 } 263 return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf)); 264} 265 266// A truism for the DbEnv object is that there is a valid 267// DB_ENV handle from the constructor until close(). 268// After the close, the DB_ENV handle is invalid and 269// no operations are permitted on the DbEnv (other than 270// destructor). Leaving the DbEnv handle open and not 271// doing a close is generally considered an error. 272// 273// We used to allow DbEnv objects to be closed and reopened. 274// This implied always keeping a valid DB_ENV object, and 275// coordinating the open objects between Db/DbEnv turned 276// out to be overly complicated. Now we do not allow this. 277 278DbEnv::DbEnv(u_int32_t flags) 279: imp_(0) 280, construct_error_(0) 281, construct_flags_(flags) 282, error_stream_(0) 283, message_stream_(0) 284, app_dispatch_callback_(0) 285, feedback_callback_(0) 286, paniccall_callback_(0) 287, event_func_callback_(0) 288, rep_send_callback_(0) 289{ 290 if ((construct_error_ = initialize(0)) != 0) 291 DB_ERROR(this, "DbEnv::DbEnv", construct_error_, 292 error_policy()); 293} 294 295DbEnv::DbEnv(DB_ENV *dbenv, u_int32_t flags) 296: imp_(0) 297, construct_error_(0) 298, construct_flags_(flags) 299, error_stream_(0) 300, message_stream_(0) 301, app_dispatch_callback_(0) 302, feedback_callback_(0) 303, paniccall_callback_(0) 304, event_func_callback_(0) 305, rep_send_callback_(0) 306{ 307 if ((construct_error_ = initialize(dbenv)) != 0) 308 DB_ERROR(this, "DbEnv::DbEnv", construct_error_, 309 error_policy()); 310} 311 312// If the DB_ENV handle is still open, we close it. This is to make stack 313// allocation of DbEnv objects easier so that they are cleaned up in the error 314// path. Note that the C layer catches cases where handles are open in the 315// environment at close time and reports an error. Applications should call 316// close explicitly in normal (non-exceptional) cases to check the return 317// value. 318// 319DbEnv::~DbEnv() 320{ 321 DB_ENV *dbenv = unwrap(this); 322 323 if (dbenv != NULL) { 324 (void)dbenv->close(dbenv, 0); 325 cleanup(); 326 } 327} 328 329// called by destructors before the DB_ENV is destroyed. 330void DbEnv::cleanup() 331{ 332 imp_ = 0; 333} 334 335int DbEnv::close(u_int32_t flags) 336{ 337 int ret; 338 DB_ENV *dbenv = unwrap(this); 339 340 ret = dbenv->close(dbenv, flags); 341 342 // after a close (no matter if success or failure), 343 // the underlying DB_ENV object must not be accessed. 344 cleanup(); 345 346 // It's safe to throw an error after the close, 347 // since our error mechanism does not peer into 348 // the DB* structures. 349 // 350 if (ret != 0) 351 DB_ERROR(this, "DbEnv::close", ret, error_policy()); 352 353 return (ret); 354} 355 356DBENV_METHOD(dbremove, 357 (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags), 358 (dbenv, unwrap(txn), name, subdb, flags)) 359DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb, 360 const char *newname, u_int32_t flags), 361 (dbenv, unwrap(txn), name, subdb, newname, flags)) 362 363void DbEnv::err(int error, const char *format, ...) 364{ 365 DB_ENV *dbenv = unwrap(this); 366 367 DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 1, format); 368} 369 370// Return a tristate value corresponding to whether we should 371// throw exceptions on errors: 372// ON_ERROR_RETURN 373// ON_ERROR_THROW 374// ON_ERROR_UNKNOWN 375// 376int DbEnv::error_policy() 377{ 378 if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { 379 return (ON_ERROR_RETURN); 380 } 381 else { 382 return (ON_ERROR_THROW); 383 } 384} 385 386void DbEnv::errx(const char *format, ...) 387{ 388 DB_ENV *dbenv = unwrap(this); 389 390 DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 1, format); 391} 392 393void *DbEnv::get_app_private() const 394{ 395 return unwrapConst(this)->app_private; 396} 397 398DBENV_METHOD(failchk, (u_int32_t flags), (dbenv, flags)) 399DBENV_METHOD(fileid_reset, (const char *file, u_int32_t flags), 400 (dbenv, file, flags)) 401DBENV_METHOD(get_home, (const char **homep), (dbenv, homep)) 402DBENV_METHOD(get_open_flags, (u_int32_t *flagsp), (dbenv, flagsp)) 403DBENV_METHOD(get_data_dirs, (const char ***dirspp), (dbenv, dirspp)) 404 405bool DbEnv::is_bigendian() 406{ 407 return unwrap(this)->is_bigendian() ? true : false; 408} 409 410DBENV_METHOD(get_thread_count, (u_int32_t *count), (dbenv, count)) 411DBENV_METHOD(set_thread_count, (u_int32_t count), (dbenv, count)) 412 413// used internally during constructor 414// to associate an existing DB_ENV with this DbEnv, 415// or create a new one. 416// 417int DbEnv::initialize(DB_ENV *dbenv) 418{ 419 int ret; 420 421 last_known_error_policy = error_policy(); 422 423 if (dbenv == 0) { 424 // Create a new DB_ENV environment. 425 if ((ret = ::db_env_create(&dbenv, 426 construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0) 427 return (ret); 428 } 429 imp_ = dbenv; 430 dbenv->api1_internal = this; // for DB_ENV* to DbEnv* conversion 431 return (0); 432} 433 434// lock methods 435DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted), 436 (dbenv, flags, atype, aborted)) 437DBENV_METHOD_ERR(lock_get, 438 (u_int32_t locker, u_int32_t flags, Dbt *obj, 439 db_lockmode_t lock_mode, DbLock *lock), 440 (dbenv, locker, flags, obj, lock_mode, &lock->lock_), 441 DbEnv::runtime_error_lock_get(this, "DbEnv::lock_get", ret, 442 DB_LOCK_GET, lock_mode, obj, *lock, 443 -1, error_policy())) 444DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp)) 445DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id)) 446DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_)) 447DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags), 448 (dbenv, statp, flags)) 449DBENV_METHOD(lock_stat_print, (u_int32_t flags), (dbenv, flags)) 450DBENV_METHOD_ERR(lock_vec, 451 (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[], 452 int nlist, DB_LOCKREQ **elist_returned), 453 (dbenv, locker, flags, list, nlist, elist_returned), 454 DbEnv::runtime_error_lock_get(this, "DbEnv::lock_vec", ret, 455 (*elist_returned)->op, (*elist_returned)->mode, 456 Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock), 457 (int)((*elist_returned) - list), error_policy())) 458// log methods 459DBENV_METHOD(log_archive, (char **list[], u_int32_t flags), 460 (dbenv, list, flags)) 461 462int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1) 463{ 464 return (::log_compare(lsn0, lsn1)); 465} 466 467// The following cast implies that DbLogc can be no larger than DB_LOGC 468DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags), 469 (dbenv, (DB_LOGC **)cursorp, flags)) 470DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len), 471 (dbenv, lsn, namep, len)) 472DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn)) 473DBENV_METHOD(log_get_config, (u_int32_t which, int *onoffp), 474 (dbenv, which, onoffp)) 475DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags), 476 (dbenv, lsn, data, flags)) 477 478int DbEnv::log_printf(DbTxn *txn, const char *fmt, ...) 479{ 480 DB_ENV *dbenv = unwrap(this); 481 va_list ap; 482 int ret; 483 484 va_start(ap, fmt); 485 ret = __log_printf_pp(dbenv, unwrap(txn), fmt, ap); 486 va_end(ap); 487 488 return (ret); 489} 490 491DBENV_METHOD(log_set_config, (u_int32_t which, int onoff), 492 (dbenv, which, onoff)) 493DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags), 494 (dbenv, spp, flags)) 495DBENV_METHOD(log_stat_print, (u_int32_t flags), (dbenv, flags)) 496 497DBENV_METHOD(lsn_reset, (const char *file, u_int32_t flags), 498 (dbenv, file, flags)) 499 500int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags) 501{ 502 DB_ENV *dbenv = unwrap(this); 503 int ret; 504 DB_MPOOLFILE *mpf; 505 506 if (dbenv == NULL) 507 ret = EINVAL; 508 else 509 ret = dbenv->memp_fcreate(dbenv, &mpf, flags); 510 511 if (DB_RETOK_STD(ret)) { 512 *dbmfp = new DbMpoolFile(); 513 (*dbmfp)->imp_ = mpf; 514 } else 515 DB_ERROR(this, "DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN); 516 517 return (ret); 518} 519 520DBENV_METHOD(memp_register, 521 (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn), 522 (dbenv, ftype, pgin_fcn, pgout_fcn)) 523 524// memory pool methods 525DBENV_METHOD(memp_stat, 526 (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags), 527 (dbenv, gsp, fsp, flags)) 528DBENV_METHOD(memp_stat_print, (u_int32_t flags), (dbenv, flags)) 529DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn)) 530DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep)) 531 532// If an error occurred during the constructor, report it now. 533// Otherwise, call the underlying DB->open method. 534// 535int DbEnv::open(const char *db_home, u_int32_t flags, int mode) 536{ 537 int ret; 538 DB_ENV *dbenv = unwrap(this); 539 540 if (construct_error_ != 0) 541 ret = construct_error_; 542 else 543 ret = dbenv->open(dbenv, db_home, flags, mode); 544 545 if (!DB_RETOK_STD(ret)) 546 DB_ERROR(this, "DbEnv::open", ret, error_policy()); 547 548 return (ret); 549} 550 551int DbEnv::remove(const char *db_home, u_int32_t flags) 552{ 553 int ret; 554 DB_ENV *dbenv = unwrap(this); 555 556 ret = dbenv->remove(dbenv, db_home, flags); 557 558 // after a remove (no matter if success or failure), 559 // the underlying DB_ENV object must not be accessed, 560 // so we clean up in advance. 561 // 562 cleanup(); 563 564 if (ret != 0) 565 DB_ERROR(this, "DbEnv::remove", ret, error_policy()); 566 567 return (ret); 568} 569 570// Report an error associated with the DbEnv. 571// error_policy is one of: 572// ON_ERROR_THROW throw an error 573// ON_ERROR_RETURN do nothing here, the caller will return an error 574// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv 575// 576void DbEnv::runtime_error(DbEnv *dbenv, 577 const char *caller, int error, int error_policy) 578{ 579 if (error_policy == ON_ERROR_UNKNOWN) 580 error_policy = last_known_error_policy; 581 if (error_policy == ON_ERROR_THROW) { 582 // Creating and throwing the object in two separate 583 // statements seems to be necessary for HP compilers. 584 switch (error) { 585 case DB_LOCK_DEADLOCK: 586 { 587 DbDeadlockException dl_except(caller); 588 dl_except.set_env(dbenv); 589 throw dl_except; 590 } 591 case DB_LOCK_NOTGRANTED: 592 { 593 DbLockNotGrantedException lng_except(caller); 594 lng_except.set_env(dbenv); 595 throw lng_except; 596 } 597 case DB_REP_HANDLE_DEAD: 598 { 599 DbRepHandleDeadException hd_except(caller); 600 hd_except.set_env(dbenv); 601 throw hd_except; 602 } 603 case DB_RUNRECOVERY: 604 { 605 DbRunRecoveryException rr_except(caller); 606 rr_except.set_env(dbenv); 607 throw rr_except; 608 } 609 default: 610 { 611 DbException except(caller, error); 612 except.set_env(dbenv); 613 throw except; 614 } 615 } 616 } 617} 618 619// Like DbEnv::runtime_error, but issue a DbMemoryException 620// based on the fact that this Dbt is not large enough. 621void DbEnv::runtime_error_dbt(DbEnv *dbenv, 622 const char *caller, Dbt *dbt, int error_policy) 623{ 624 if (error_policy == ON_ERROR_UNKNOWN) 625 error_policy = last_known_error_policy; 626 if (error_policy == ON_ERROR_THROW) { 627 // Creating and throwing the object in two separate 628 // statements seems to be necessary for HP compilers. 629 DbMemoryException except(caller, dbt); 630 except.set_env(dbenv); 631 throw except; 632 } 633} 634 635// Like DbEnv::runtime_error, but issue a DbLockNotGrantedException, 636// or a regular runtime error. 637// call regular runtime_error if it 638void DbEnv::runtime_error_lock_get(DbEnv *dbenv, 639 const char *caller, int error, 640 db_lockop_t op, db_lockmode_t mode, Dbt *obj, 641 DbLock lock, int index, int error_policy) 642{ 643 if (error != DB_LOCK_NOTGRANTED) { 644 runtime_error(dbenv, caller, error, error_policy); 645 return; 646 } 647 648 if (error_policy == ON_ERROR_UNKNOWN) 649 error_policy = last_known_error_policy; 650 if (error_policy == ON_ERROR_THROW) { 651 // Creating and throwing the object in two separate 652 // statements seems to be necessary for HP compilers. 653 DbLockNotGrantedException except(caller, op, mode, 654 obj, lock, index); 655 except.set_env(dbenv); 656 throw except; 657 } 658} 659 660void DbEnv::_stream_error_function( 661 const DB_ENV *dbenv, const char *prefix, const char *message) 662{ 663 const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv); 664 if (cxxenv == 0) { 665 DB_ERROR(0, 666 "DbEnv::stream_error", EINVAL, ON_ERROR_UNKNOWN); 667 return; 668 } 669 670 if (cxxenv->error_callback_) 671 cxxenv->error_callback_(cxxenv, prefix, message); 672 else if (cxxenv->error_stream_) { 673 // HP compilers need the extra casts, we don't know why. 674 if (prefix) { 675 (*cxxenv->error_stream_) << prefix; 676 (*cxxenv->error_stream_) << (const char *)": "; 677 } 678 if (message) 679 (*cxxenv->error_stream_) << (const char *)message; 680 (*cxxenv->error_stream_) << (const char *)"\n"; 681 } 682} 683 684void DbEnv::_stream_message_function(const DB_ENV *dbenv, const char *message) 685{ 686 const DbEnv *cxxenv = DbEnv::get_const_DbEnv(dbenv); 687 if (cxxenv == 0) { 688 DB_ERROR(0, 689 "DbEnv::stream_message", EINVAL, ON_ERROR_UNKNOWN); 690 return; 691 } 692 693 if (cxxenv->message_callback_) 694 cxxenv->message_callback_(cxxenv, message); 695 else if (cxxenv->message_stream_) { 696 // HP compilers need the extra casts, we don't know why. 697 (*cxxenv->message_stream_) << (const char *)message; 698 (*cxxenv->message_stream_) << (const char *)"\n"; 699 } 700} 701 702// static method 703char *DbEnv::strerror(int error) 704{ 705 return (db_strerror(error)); 706} 707 708// We keep these alphabetical by field name, 709// for comparison with Java's list. 710// 711DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir)) 712DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp), 713 (dbenv, flagsp)) 714DBENV_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), 715 (dbenv, passwd, flags)) 716DBENV_METHOD_VOID(get_errfile, (FILE **errfilep), (dbenv, errfilep)) 717DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile)) 718DBENV_METHOD_VOID(get_errpfx, (const char **errpfxp), (dbenv, errpfxp)) 719DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx)) 720DBENV_METHOD(get_intermediate_dir_mode, (const char **modep), (dbenv, modep)) 721DBENV_METHOD(set_intermediate_dir_mode, (const char *mode), (dbenv, mode)) 722DBENV_METHOD(get_lg_bsize, (u_int32_t *bsizep), (dbenv, bsizep)) 723DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize)) 724DBENV_METHOD(get_lg_dir, (const char **dirp), (dbenv, dirp)) 725DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir)) 726DBENV_METHOD(get_lg_filemode, (int *modep), (dbenv, modep)) 727DBENV_METHOD(set_lg_filemode, (int mode), (dbenv, mode)) 728DBENV_METHOD(get_lg_max, (u_int32_t *maxp), (dbenv, maxp)) 729DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max)) 730DBENV_METHOD(get_lg_regionmax, (u_int32_t *regionmaxp), (dbenv, regionmaxp)) 731DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax)) 732DBENV_METHOD(get_lk_conflicts, (const u_int8_t **lk_conflictsp, int *lk_maxp), 733 (dbenv, lk_conflictsp, lk_maxp)) 734DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max), 735 (dbenv, lk_conflicts, lk_max)) 736DBENV_METHOD(get_lk_detect, (u_int32_t *detectp), (dbenv, detectp)) 737DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect)) 738DBENV_METHOD(get_lk_max_lockers, (u_int32_t *max_lockersp), 739 (dbenv, max_lockersp)) 740DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers)) 741DBENV_METHOD(get_lk_max_locks, (u_int32_t *max_locksp), (dbenv, max_locksp)) 742DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks)) 743DBENV_METHOD(get_lk_max_objects, (u_int32_t *max_objectsp), 744 (dbenv, max_objectsp)) 745DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects)) 746DBENV_METHOD(get_lk_partitions, (u_int32_t *partitionsp), (dbenv, partitionsp)) 747DBENV_METHOD(set_lk_partitions, (u_int32_t partitions), (dbenv, partitions)) 748DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp)) 749DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd)) 750DBENV_METHOD(get_mp_max_write, (int *maxwritep, db_timeout_t *maxwrite_sleepp), 751 (dbenv, maxwritep, maxwrite_sleepp)) 752DBENV_METHOD(set_mp_max_write, (int maxwrite, db_timeout_t maxwrite_sleep), 753 (dbenv, maxwrite, maxwrite_sleep)) 754DBENV_METHOD(get_mp_mmapsize, (size_t *mmapsizep), (dbenv, mmapsizep)) 755DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize)) 756DBENV_METHOD(get_mp_pagesize, (u_int32_t *pagesizep), (dbenv, pagesizep)) 757DBENV_METHOD(set_mp_pagesize, (u_int32_t pagesize), (dbenv, pagesize)) 758DBENV_METHOD(get_mp_tablesize, (u_int32_t *tablesizep), (dbenv, tablesizep)) 759DBENV_METHOD(set_mp_tablesize, (u_int32_t tablesize), (dbenv, tablesize)) 760DBENV_METHOD_VOID(get_msgfile, (FILE **msgfilep), (dbenv, msgfilep)) 761DBENV_METHOD_VOID(set_msgfile, (FILE *msgfile), (dbenv, msgfile)) 762DBENV_METHOD(get_tmp_dir, (const char **tmp_dirp), (dbenv, tmp_dirp)) 763DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir)) 764DBENV_METHOD(get_tx_max, (u_int32_t *tx_maxp), (dbenv, tx_maxp)) 765DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max)) 766 767DBENV_METHOD(stat_print, (u_int32_t flags), (dbenv, flags)) 768 769DBENV_METHOD_QUIET(get_alloc, 770 (db_malloc_fcn_type *malloc_fcnp, db_realloc_fcn_type *realloc_fcnp, 771 db_free_fcn_type *free_fcnp), 772 (dbenv, malloc_fcnp, realloc_fcnp, free_fcnp)) 773 774DBENV_METHOD_QUIET(set_alloc, 775 (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn, 776 db_free_fcn_type free_fcn), 777 (dbenv, malloc_fcn, realloc_fcn, free_fcn)) 778 779void DbEnv::set_app_private(void *value) 780{ 781 unwrap(this)->app_private = value; 782} 783 784DBENV_METHOD(get_cachesize, 785 (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), 786 (dbenv, gbytesp, bytesp, ncachep)) 787DBENV_METHOD(set_cachesize, 788 (u_int32_t gbytes, u_int32_t bytes, int ncache), 789 (dbenv, gbytes, bytes, ncache)) 790DBENV_METHOD(get_cache_max, (u_int32_t *gbytesp, u_int32_t *bytesp), 791 (dbenv, gbytesp, bytesp)) 792DBENV_METHOD(set_cache_max, (u_int32_t gbytes, u_int32_t bytes), 793 (dbenv, gbytes, bytes)) 794DBENV_METHOD(get_create_dir, (const char **dirp), (dbenv, dirp)) 795DBENV_METHOD(set_create_dir, (const char *dir), (dbenv, dir)) 796 797void DbEnv::get_errcall(void (**argp)(const DbEnv *, const char *, const char *)) 798{ 799 if (argp != NULL) 800 *argp = error_callback_; 801 return; 802} 803 804void DbEnv::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) 805{ 806 DB_ENV *dbenv = unwrap(this); 807 808 error_callback_ = arg; 809 error_stream_ = 0; 810 811 dbenv->set_errcall(dbenv, (arg == 0) ? 0 : 812 _stream_error_function_c); 813} 814 815__DB_STD(ostream) *DbEnv::get_error_stream() 816{ 817 return (error_stream_); 818} 819 820void DbEnv::set_error_stream(__DB_STD(ostream) *stream) 821{ 822 DB_ENV *dbenv = unwrap(this); 823 824 error_stream_ = stream; 825 error_callback_ = 0; 826 827 dbenv->set_errcall(dbenv, (stream == 0) ? 0 : 828 _stream_error_function_c); 829} 830 831int DbEnv::get_feedback(void (**argp)(DbEnv *, int, int)) 832{ 833 if (argp != NULL) 834 *argp = feedback_callback_; 835 return 0; 836} 837 838int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int)) 839{ 840 DB_ENV *dbenv = unwrap(this); 841 842 feedback_callback_ = arg; 843 844 return (dbenv->set_feedback(dbenv, 845 arg == 0 ? 0 : _feedback_intercept_c)); 846} 847 848DBENV_METHOD(get_flags, (u_int32_t *flagsp), (dbenv, flagsp)) 849DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff)) 850 851void DbEnv::get_msgcall(void (**argp)(const DbEnv *, const char *)) 852{ 853 if (argp != NULL) 854 *argp = message_callback_; 855} 856 857void DbEnv::set_msgcall(void (*arg)(const DbEnv *, const char *)) 858{ 859 DB_ENV *dbenv = unwrap(this); 860 861 message_callback_ = arg; 862 message_stream_ = 0; 863 864 dbenv->set_msgcall(dbenv, (arg == 0) ? 0 : 865 _stream_message_function_c); 866} 867 868__DB_STD(ostream) *DbEnv::get_message_stream() 869{ 870 return (message_stream_); 871} 872 873void DbEnv::set_message_stream(__DB_STD(ostream) *stream) 874{ 875 DB_ENV *dbenv = unwrap(this); 876 877 message_stream_ = stream; 878 message_callback_ = 0; 879 880 dbenv->set_msgcall(dbenv, (stream == 0) ? 0 : 881 _stream_message_function_c); 882} 883 884int DbEnv::set_paniccall(void (*arg)(DbEnv *, int)) 885{ 886 DB_ENV *dbenv = unwrap(this); 887 888 paniccall_callback_ = arg; 889 890 return (dbenv->set_paniccall(dbenv, 891 arg == 0 ? 0 : _paniccall_intercept_c)); 892} 893 894int DbEnv::set_event_notify(void (*arg)(DbEnv *, u_int32_t, void *)) 895{ 896 DB_ENV *dbenv = unwrap(this); 897 898 event_func_callback_ = arg; 899 900 return (dbenv->set_event_notify(dbenv, 901 arg == 0 ? 0 : _event_func_intercept_c)); 902} 903 904DBENV_METHOD(set_rpc_server, 905 (void *cl, char *host, long tsec, long ssec, u_int32_t flags), 906 (dbenv, cl, host, tsec, ssec, flags)) 907DBENV_METHOD(get_shm_key, (long *shm_keyp), (dbenv, shm_keyp)) 908DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key)) 909 910int DbEnv::get_app_dispatch 911 (int (**argp)(DbEnv *, Dbt *, DbLsn *, db_recops)) 912{ 913 if (argp != NULL) 914 *argp = app_dispatch_callback_; 915 return 0; 916} 917 918int DbEnv::set_app_dispatch 919 (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops)) 920{ 921 DB_ENV *dbenv = unwrap(this); 922 int ret; 923 924 app_dispatch_callback_ = arg; 925 if ((ret = dbenv->set_app_dispatch(dbenv, 926 arg == 0 ? 0 : _app_dispatch_intercept_c)) != 0) 927 DB_ERROR(this, "DbEnv::set_app_dispatch", ret, error_policy()); 928 929 return (ret); 930} 931 932int DbEnv::get_isalive 933 (int (**argp)(DbEnv *, pid_t, db_threadid_t, u_int32_t)) 934{ 935 if (argp != NULL) 936 *argp = isalive_callback_; 937 return 0; 938} 939 940int DbEnv::set_isalive 941 (int (*arg)(DbEnv *, pid_t, db_threadid_t, u_int32_t)) 942{ 943 DB_ENV *dbenv = unwrap(this); 944 int ret; 945 946 isalive_callback_ = arg; 947 if ((ret = dbenv->set_isalive(dbenv, 948 arg == 0 ? 0 : _isalive_intercept_c)) != 0) 949 DB_ERROR(this, "DbEnv::set_isalive", ret, error_policy()); 950 951 return (ret); 952} 953 954DBENV_METHOD(get_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) 955DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) 956DBENV_METHOD(get_verbose, (u_int32_t which, int *onoffp), 957 (dbenv, which, onoffp)) 958DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff)) 959 960DBENV_METHOD(mutex_alloc, 961 (u_int32_t flags, db_mutex_t *mutexp), (dbenv, flags, mutexp)) 962DBENV_METHOD(mutex_free, (db_mutex_t mutex), (dbenv, mutex)) 963DBENV_METHOD(mutex_get_align, (u_int32_t *argp), (dbenv, argp)) 964DBENV_METHOD(mutex_get_increment, (u_int32_t *argp), (dbenv, argp)) 965DBENV_METHOD(mutex_get_max, (u_int32_t *argp), (dbenv, argp)) 966DBENV_METHOD(mutex_get_tas_spins, (u_int32_t *argp), (dbenv, argp)) 967DBENV_METHOD(mutex_lock, (db_mutex_t mutex), (dbenv, mutex)) 968DBENV_METHOD(mutex_set_align, (u_int32_t arg), (dbenv, arg)) 969DBENV_METHOD(mutex_set_increment, (u_int32_t arg), (dbenv, arg)) 970DBENV_METHOD(mutex_set_max, (u_int32_t arg), (dbenv, arg)) 971DBENV_METHOD(mutex_set_tas_spins, (u_int32_t arg), (dbenv, arg)) 972DBENV_METHOD(mutex_stat, 973 (DB_MUTEX_STAT **statp, u_int32_t flags), (dbenv, statp, flags)) 974DBENV_METHOD(mutex_stat_print, (u_int32_t flags), (dbenv, flags)) 975DBENV_METHOD(mutex_unlock, (db_mutex_t mutex), (dbenv, mutex)) 976 977int DbEnv::get_thread_id_fn(void (**argp)(DbEnv *, pid_t *, db_threadid_t *)) 978{ 979 if (argp != NULL) 980 *argp = thread_id_callback_; 981 return 0; 982} 983 984int DbEnv::set_thread_id(void (*arg)(DbEnv *, pid_t *, db_threadid_t *)) 985{ 986 DB_ENV *dbenv = unwrap(this); 987 int ret; 988 989 thread_id_callback_ = arg; 990 if ((ret = dbenv->set_thread_id(dbenv, 991 arg == 0 ? 0 : _thread_id_intercept_c)) != 0) 992 DB_ERROR(this, "DbEnv::set_thread_id", ret, error_policy()); 993 994 return (ret); 995} 996 997int DbEnv::get_thread_id_string_fn( 998 char *(**argp)(DbEnv *, pid_t, db_threadid_t, char *)) 999{ 1000 if (argp != NULL) 1001 *argp = thread_id_string_callback_; 1002 return 0; 1003} 1004 1005int DbEnv::set_thread_id_string( 1006 char *(*arg)(DbEnv *, pid_t, db_threadid_t, char *)) 1007{ 1008 DB_ENV *dbenv = unwrap(this); 1009 int ret; 1010 1011 thread_id_string_callback_ = arg; 1012 if ((ret = dbenv->set_thread_id_string(dbenv, 1013 arg == 0 ? 0 : _thread_id_string_intercept_c)) != 0) 1014 DB_ERROR(this, "DbEnv::set_thread_id_string", ret, 1015 error_policy()); 1016 1017 return (ret); 1018} 1019 1020DBENV_METHOD(add_data_dir, (const char *dir), (dbenv, dir)) 1021 1022int DbEnv::cdsgroup_begin(DbTxn **tid) 1023{ 1024 DB_ENV *dbenv = unwrap(this); 1025 DB_TXN *txn; 1026 int ret; 1027 1028 ret = dbenv->cdsgroup_begin(dbenv, &txn); 1029 if (DB_RETOK_STD(ret)) 1030 *tid = new DbTxn(txn, NULL); 1031 else 1032 DB_ERROR(this, "DbEnv::cdsgroup_begin", ret, error_policy()); 1033 1034 return (ret); 1035} 1036 1037int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags) 1038{ 1039 DB_ENV *dbenv = unwrap(this); 1040 DB_TXN *txn; 1041 int ret; 1042 1043 ret = dbenv->txn_begin(dbenv, unwrap(pid), &txn, flags); 1044 if (DB_RETOK_STD(ret)) 1045 *tid = new DbTxn(txn, pid); 1046 else 1047 DB_ERROR(this, "DbEnv::txn_begin", ret, error_policy()); 1048 1049 return (ret); 1050} 1051 1052DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags), 1053 (dbenv, kbyte, min, flags)) 1054 1055int DbEnv::txn_recover(DbPreplist *preplist, u_int32_t count, 1056 u_int32_t *retp, u_int32_t flags) 1057{ 1058 DB_ENV *dbenv = unwrap(this); 1059 DB_PREPLIST *c_preplist; 1060 u_int32_t i; 1061 int ret; 1062 1063 /* 1064 * We need to allocate some local storage for the 1065 * returned preplist, and that requires us to do 1066 * our own argument validation. 1067 */ 1068 if (count <= 0) 1069 ret = EINVAL; 1070 else 1071 ret = __os_malloc(dbenv->env, sizeof(DB_PREPLIST) * count, 1072 &c_preplist); 1073 1074 if (ret != 0) { 1075 DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); 1076 return (ret); 1077 } 1078 1079 if ((ret = 1080 dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) { 1081 __os_free(dbenv->env, c_preplist); 1082 DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); 1083 return (ret); 1084 } 1085 1086 for (i = 0; i < *retp; i++) { 1087 preplist[i].txn = new DbTxn(NULL); 1088 preplist[i].txn->imp_ = c_preplist[i].txn; 1089 memcpy(preplist[i].gid, c_preplist[i].gid, 1090 sizeof(preplist[i].gid)); 1091 } 1092 1093 __os_free(dbenv->env, c_preplist); 1094 1095 return (0); 1096} 1097 1098DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags), 1099 (dbenv, statp, flags)) 1100DBENV_METHOD(txn_stat_print, (u_int32_t flags), (dbenv, flags)) 1101 1102int DbEnv::rep_set_transport(int myid, int (*arg)(DbEnv *, 1103 const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)) 1104{ 1105 DB_ENV *dbenv = unwrap(this); 1106 int ret; 1107 1108 rep_send_callback_ = arg; 1109 if ((ret = dbenv->rep_set_transport(dbenv, myid, 1110 arg == 0 ? 0 : _rep_send_intercept_c)) != 0) 1111 DB_ERROR(this, "DbEnv::rep_set_transport", ret, error_policy()); 1112 1113 return (ret); 1114} 1115 1116DBENV_METHOD(rep_elect, (u_int32_t nsites, u_int32_t nvotes, u_int32_t flags), 1117 (dbenv, nsites, nvotes, flags)) 1118DBENV_METHOD(rep_flush, (), (dbenv)) 1119DBENV_METHOD(rep_get_config, (u_int32_t which, int *onoffp), 1120 (dbenv, which, onoffp)) 1121DBENV_METHOD(rep_get_request, (u_int32_t *min, u_int32_t *max), 1122 (dbenv, min, max)) 1123DBENV_METHOD(rep_set_request, (u_int32_t min, u_int32_t max), (dbenv, min, max)) 1124 1125int DbEnv::rep_process_message(Dbt *control, 1126 Dbt *rec, int id, DbLsn *ret_lsnp) 1127{ 1128 DB_ENV *dbenv = unwrap(this); 1129 int ret; 1130 1131 ret = dbenv->rep_process_message(dbenv, control, rec, id, ret_lsnp); 1132 if (!DB_RETOK_REPPMSG(ret)) 1133 DB_ERROR(this, "DbEnv::rep_process_message", ret, 1134 error_policy()); 1135 1136 return (ret); 1137} 1138 1139DBENV_METHOD(rep_set_config, 1140 (u_int32_t which, int onoff), (dbenv, which, onoff)) 1141DBENV_METHOD(rep_start, 1142 (Dbt *cookie, u_int32_t flags), 1143 (dbenv, (DBT *)cookie, flags)) 1144 1145DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags), 1146 (dbenv, statp, flags)) 1147DBENV_METHOD(rep_stat_print, (u_int32_t flags), (dbenv, flags)) 1148DBENV_METHOD(rep_sync, (u_int32_t flags), (dbenv, flags)) 1149 1150DBENV_METHOD(rep_get_clockskew, (u_int32_t *fast_clockp, u_int32_t *slow_clockp), 1151 (dbenv, fast_clockp, slow_clockp)) 1152DBENV_METHOD(rep_set_clockskew, (u_int32_t fast_clock, u_int32_t slow_clock), 1153 (dbenv, fast_clock, slow_clock)) 1154DBENV_METHOD(rep_get_limit, (u_int32_t *gbytesp, u_int32_t *bytesp), 1155 (dbenv, gbytesp, bytesp)) 1156DBENV_METHOD(rep_set_limit, (u_int32_t gbytes, u_int32_t bytes), 1157 (dbenv, gbytes, bytes)) 1158 1159// 1160// Begin advanced replication API method implementations 1161DBENV_METHOD(rep_get_nsites, (u_int32_t *n), (dbenv, n)) 1162DBENV_METHOD(rep_set_nsites, (u_int32_t n), (dbenv, n)) 1163DBENV_METHOD(rep_get_priority, (u_int32_t *priority), 1164 (dbenv, priority)) 1165DBENV_METHOD(rep_set_priority, (u_int32_t priority), 1166 (dbenv, priority)) 1167DBENV_METHOD(rep_get_timeout, (int which, db_timeout_t * timeout), 1168 (dbenv, which, timeout)) 1169DBENV_METHOD(rep_set_timeout, (int which, db_timeout_t timeout), 1170 (dbenv, which, timeout)) 1171DBENV_METHOD(repmgr_add_remote_site, (const char* host, u_int16_t port, 1172 int * eidp, u_int32_t flags), (dbenv, host, port, eidp, flags)) 1173DBENV_METHOD(repmgr_get_ack_policy, (int *policy), (dbenv, policy)) 1174DBENV_METHOD(repmgr_set_ack_policy, (int policy), (dbenv, policy)) 1175DBENV_METHOD(repmgr_set_local_site, (const char* host, u_int16_t port, 1176 u_int32_t flags), (dbenv, host, port, flags)) 1177DBENV_METHOD(repmgr_site_list, (u_int *countp, DB_REPMGR_SITE **listp), 1178 (dbenv, countp, listp)) 1179 1180int DbEnv::repmgr_start(int nthreads, u_int32_t flags) 1181{ 1182 DB_ENV *dbenv = unwrap(this); 1183 int ret; 1184 1185 ret = dbenv->repmgr_start(dbenv, nthreads, flags); 1186 if (!DB_RETOK_REPMGR_START(ret)) 1187 DB_ERROR(this, "DbEnv::repmgr_start", ret, 1188 error_policy()); 1189 1190 return (ret); 1191} 1192 1193DBENV_METHOD(repmgr_stat, (DB_REPMGR_STAT **statp, u_int32_t flags), 1194 (dbenv, statp, flags)) 1195DBENV_METHOD(repmgr_stat_print, (u_int32_t flags), (dbenv, flags)) 1196 1197// End advanced replication API method implementations. 1198 1199DBENV_METHOD(get_timeout, 1200 (db_timeout_t *timeoutp, u_int32_t flags), 1201 (dbenv, timeoutp, flags)) 1202DBENV_METHOD(set_timeout, 1203 (db_timeout_t timeout, u_int32_t flags), 1204 (dbenv, timeout, flags)) 1205 1206// static method 1207char *DbEnv::version(int *major, int *minor, int *patch) 1208{ 1209 return (db_version(major, minor, patch)); 1210} 1211 1212// static method 1213DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv) 1214{ 1215 DbEnv *wrapped_env = get_DbEnv(dbenv); 1216 return (wrapped_env != NULL) ? wrapped_env : new DbEnv(dbenv, 0); 1217} 1218