00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef XCT_H
00054 #define XCT_H
00055
00056 #include "w_defines.h"
00057
00058
00059
00060 #ifdef __GNUG__
00061 #pragma interface
00062 #endif
00063
00064 #if W_DEBUG_LEVEL > 2
00065
00066
00067
00068
00069 #define X_LOG_COMMENT_ON 1
00070 #define ADD_LOG_COMMENT_SIG ,const char *debugmsg
00071 #define ADD_LOG_COMMENT_USE ,debugmsg
00072 #define X_LOG_COMMENT_USE(x) ,x
00073
00074 #else
00075
00076 #define X_LOG_COMMENT_ON 0
00077 #define ADD_LOG_COMMENT_SIG
00078 #define ADD_LOG_COMMENT_USE
00079 #define X_LOG_COMMENT_USE(x)
00080 #endif
00081
00082 class xct_dependent_t;
00083
00084
00085
00086
00087
00088
00089
00090 class xct_log_t : public smlevel_1 {
00091 private:
00092
00093 bool _xct_log_off;
00094 public:
00095 NORET xct_log_t(): _xct_log_off(false) {};
00096 bool xct_log_is_off() { return _xct_log_off; }
00097 void set_xct_log_off() { _xct_log_off = true; }
00098 void set_xct_log_on() { _xct_log_off = false; }
00099 };
00100
00101
00102 class lockid_t;
00103 class sdesc_cache_t;
00104 class xct_i;
00105 class restart_m;
00106 class lock_m;
00107 class lock_core_m;
00108 class lock_request_t;
00109 class xct_log_switch_t;
00110 class xct_lock_info_t;
00111 class xct_prepare_alk_log;
00112 class xct_prepare_fi_log;
00113 class xct_prepare_lk_log;
00114 class sm_quark_t;
00115 class smthread_t;
00116
00117 class logrec_t;
00118 class page_p;
00119
00120
00121
00122
00123
00124
00125 class stid_list_elem_t {
00126 public:
00127 stid_t stid;
00128 w_link_t _link;
00129
00130 stid_list_elem_t(const stid_t& theStid)
00131 : stid(theStid)
00132 {};
00133 ~stid_list_elem_t()
00134 {
00135 if (_link.member_of() != NULL)
00136 _link.detach();
00137 }
00138 static w_base_t::uint4_t link_offset()
00139 {
00140 return W_LIST_ARG(stid_list_elem_t, _link);
00141 }
00142 };
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 class xct_t : public smlevel_1 {
00155
00156 #if USE_BLOCK_ALLOC_FOR_LOGREC
00157 friend class block_alloc<xct_t>;
00158 #endif
00159 friend class xct_i;
00160 friend class smthread_t;
00161 friend class restart_m;
00162 friend class lock_m;
00163 friend class lock_core_m;
00164 friend class lock_request_t;
00165 friend class xct_log_switch_t;
00166 friend class xct_prepare_alk_log;
00167 friend class xct_prepare_fi_log;
00168 friend class xct_prepare_lk_log;
00169 friend class sm_quark_t;
00170
00171 protected:
00172 enum commit_t { t_normal = 0, t_lazy = 1, t_chain = 2, t_group = 4 };
00173
00174
00175
00176 public:
00177 typedef xct_state_t state_t;
00178
00179 static
00180 xct_t* new_xct(
00181 sm_stats_info_t* stats = 0,
00182 timeout_in_ms timeout = WAIT_SPECIFIED_BY_THREAD);
00183
00184 static
00185 xct_t* new_xct(
00186 const tid_t& tid,
00187 state_t s,
00188 const lsn_t& last_lsn,
00189 const lsn_t& undo_nxt,
00190 timeout_in_ms timeout = WAIT_SPECIFIED_BY_THREAD);
00191 static
00192 void destroy_xct(xct_t* xd);
00193
00194 static
00195 rc_t group_commit(const xct_t *list[], int number);
00196
00197 rc_t commit_free_locks();
00198
00199 #if defined(USE_BLOCK_ALLOC_FOR_XCT_IMPL) && (USE_BLOCK_ALLOC_FOR_XCT_IMPL==1)
00200 public:
00201 #else
00202 private:
00203 #endif
00204 struct xct_core;
00205 private:
00206 NORET xct_t(
00207 xct_core* core,
00208 sm_stats_info_t* stats,
00209 const lsn_t& last_lsn,
00210 const lsn_t& undo_nxt);
00211 NORET ~xct_t();
00212
00213 public:
00214
00215 friend ostream& operator<<(ostream&, const xct_t&);
00216
00217 static int collect(vtable_t&, bool names_too);
00218 void vtable_collect(vtable_row_t &);
00219 static void vtable_collect_names(vtable_row_t &);
00220
00221 state_t state() const;
00222 void set_timeout(timeout_in_ms t) ;
00223
00224 timeout_in_ms timeout_c() const;
00225
00226
00227
00228
00229 public:
00230 void force_readonly();
00231 bool forced_readonly() const;
00232
00233 vote_t vote() const;
00234 bool is_extern2pc() const;
00235 rc_t enter2pc(const gtid_t &g);
00236 const gtid_t* gtid() const;
00237 const server_handle_t& get_coordinator()const;
00238 void set_coordinator(const server_handle_t &);
00239 static rc_t recover2pc(const gtid_t &g,
00240 bool mayblock, xct_t *&);
00241 static rc_t query_prepared(int &numtids);
00242 static rc_t query_prepared(int numtids, gtid_t l[]);
00243
00244 rc_t prepare();
00245 rc_t log_prepared(bool in_chkpt=false);
00246
00247
00248
00249
00250 public:
00251 static void dump(ostream &o);
00252 static int cleanup(bool dispose_prepared=false);
00253
00254
00255
00256 bool is_instrumented() {
00257 return (__stats != 0);
00258 }
00259 void give_stats(sm_stats_info_t* s) {
00260 w_assert1(__stats == 0);
00261 __stats = s;
00262 }
00263 void clear_stats() {
00264 memset(__stats,0, sizeof(*__stats));
00265 }
00266 sm_stats_info_t* steal_stats() {
00267 sm_stats_info_t*s = __stats;
00268 __stats = 0;
00269 return s;
00270 }
00271 const sm_stats_info_t& const_stats_ref() { return *__stats; }
00272 rc_t commit(bool lazy = false, lsn_t* plastlsn=NULL);
00273 rc_t commit_as_group_member();
00274 rc_t rollback(const lsn_t &save_pt);
00275 rc_t save_point(lsn_t& lsn);
00276 rc_t chain(bool lazy = false);
00277 rc_t abort(bool save_stats = false);
00278
00279
00280 protected:
00281 sm_stats_info_t& stats_ref() { return *__stats; }
00282 rc_t dispose();
00283 void change_state(state_t new_state);
00284 void set_first_lsn(const lsn_t &) ;
00285 void set_last_lsn(const lsn_t &) ;
00286 void set_undo_nxt(const lsn_t &) ;
00287 void prepare_restore_log_resv(int, int, int, int);
00288
00289
00290 public:
00291
00292
00293 const lsn_t& last_lsn() const;
00294 const lsn_t& first_lsn() const;
00295 const lsn_t& undo_nxt() const;
00296 const logrec_t* last_log() const;
00297 fileoff_t get_log_space_used() const;
00298 rc_t wait_for_log_space(fileoff_t amt);
00299
00300
00301 static xct_t* look_up(const tid_t& tid);
00302 static tid_t oldest_tid();
00303 static tid_t youngest_tid();
00304
00305 static void update_youngest_tid(const tid_t &);
00306
00307
00308
00309 static w_base_t::uint4_t num_active_xcts();
00310
00311
00312
00313 const lsn_t& anchor(bool grabit = true);
00314 void release_anchor(bool compensate
00315 ADD_LOG_COMMENT_SIG
00316 );
00317 int compensated_op_depth() const ;
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 void start_crit() {
00338
00339 w_assert0(update_threads() == 1);
00340 }
00341 void stop_crit() {}
00342
00343
00344 void compensate(const lsn_t&,
00345 bool undoable
00346 ADD_LOG_COMMENT_SIG
00347 );
00348
00349 void compensate_undo(const lsn_t&);
00350
00351
00352
00353
00354
00355
00356
00357 void log_warn_disable();
00358 void log_warn_resume();
00359 bool log_warn_is_on() const;
00360
00361
00362
00363 public:
00364
00365 rc_t add_dependent(xct_dependent_t* dependent);
00366 rc_t remove_dependent(xct_dependent_t* dependent);
00367 bool find_dependent(xct_dependent_t* dependent);
00368
00369
00370
00371
00372 bool is_log_on() const;
00373 rc_t get_logbuf(logrec_t*&, int t,
00374 const page_p *p = 0);
00375 rc_t give_logbuf(logrec_t*, const page_p *p = 0);
00376
00377
00378
00379
00380 void AddStoreToFree(const stid_t& stid);
00381 void AddLoadStore(const stid_t& stid);
00382
00383 void set_alloced() { }
00384
00385 void num_extents_marked_for_deletion(
00386 base_stat_t &num);
00387 public:
00388
00389 void GetEscalationThresholds(
00390 w_base_t::int4_t &toPage,
00391 w_base_t::int4_t &toStore,
00392 w_base_t::int4_t &toVolume);
00393 void SetEscalationThresholds(
00394 w_base_t::int4_t toPage,
00395 w_base_t::int4_t toStore,
00396 w_base_t::int4_t toVolume);
00397 bool set_lock_cache_enable(bool enable);
00398 bool lock_cache_enabled();
00399
00400 protected:
00401
00402
00403
00404
00405 static lockid_t* new_lock_hierarchy();
00406 static sdesc_cache_t* new_sdesc_cache_t();
00407 static xct_log_t* new_xct_log_t();
00408 void steal(lockid_t*&, sdesc_cache_t*&, xct_log_t*&);
00409 void stash(lockid_t*&, sdesc_cache_t*&, xct_log_t*&);
00410
00411 void attach_thread();
00412 void detach_thread();
00413
00414
00415
00416 lockid_t* lock_info_hierarchy() const {
00417 return me()->lock_hierarchy();
00418 }
00419 public:
00420
00421 sdesc_cache_t* sdesc_cache() const;
00422
00423 protected:
00424
00425
00426 switch_t set_log_state(switch_t s);
00427
00428 void restore_log_state(switch_t s);
00429
00430
00431 public:
00432 concurrency_t get_lock_level();
00433 void lock_level(concurrency_t l);
00434
00435 int num_threads();
00436 rc_t check_one_thread_attached() const;
00437 int attach_update_thread();
00438 void detach_update_thread();
00439 int update_threads() const;
00440
00441 protected:
00442
00443 w_rc_t lockblock(timeout_in_ms timeout);
00444 void lockunblock();
00445 const w_base_t::int4_t* GetEscalationThresholdsArray();
00446
00447 rc_t check_lock_totals(int nex,
00448 int nix, int nsix, int ) const;
00449 rc_t obtain_locks(lock_mode_t mode,
00450 int nlks, const lockid_t *l);
00451 rc_t obtain_one_lock(lock_mode_t mode,
00452 const lockid_t &l);
00453
00454 xct_lock_info_t* lock_info() const;
00455
00456 public:
00457
00458
00459
00460 static w_rc_t acquire_xlist_mutex();
00461 static void release_xlist_mutex();
00462 static void assert_xlist_mutex_not_mine();
00463 static void assert_xlist_mutex_is_mine();
00464 static bool xlist_mutex_is_mine();
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 void force_nonblocking();
00480
00481
00482
00483
00484
00485 protected:
00486
00487 w_link_t _xlink;
00488 static w_descend_list_t<xct_t, queue_based_lock_t, tid_t> _xlist;
00489 void put_in_order();
00490 private:
00491 static queue_based_lock_t _xlist_mutex;
00492
00493 sm_stats_info_t* __stats;
00494 lockid_t* __saved_lockid_t;
00495 sdesc_cache_t* __saved_sdesc_cache_t;
00496 xct_log_t* __saved_xct_log_t;
00497
00498 static tid_t _nxt_tid;
00499
00500 static tid_t _oldest_tid;
00501
00502
00503
00504 tid_t _tid;
00505
00506 public:
00507 void acquire_1thread_xct_mutex() const;
00508 void release_1thread_xct_mutex() const;
00509 bool is_1thread_log_mutex_mine() const {
00510 return
00511 me()->is_update_thread()
00512 ||
00513 smlevel_0::in_recovery()
00514 ;
00515 }
00516
00517
00518 private:
00519 void acquire_1thread_log_mutex() {
00520
00521
00522
00523
00524 w_assert0(me()->is_update_thread() || smlevel_0::in_recovery());
00525 }
00526 void release_1thread_log_mutex() {
00527
00528
00529
00530
00531 w_assert0(me()->is_update_thread() || smlevel_0::in_recovery());
00532 }
00533 private:
00534 bool is_1thread_xct_mutex_mine() const;
00535 void assert_1thread_xct_mutex_free()const;
00536
00537 rc_t _abort();
00538 rc_t _commit(w_base_t::uint4_t flags,
00539 lsn_t* plastlsn=NULL);
00540
00541 protected:
00542
00543 switch_t set_log_state(switch_t s, bool &nested);
00544 void restore_log_state(switch_t s, bool nested);
00545
00546 private:
00547 bool one_thread_attached() const;
00548
00549 void _compensate(const lsn_t&, bool undoable = false);
00550
00551 w_base_t::int4_t escalationThresholds[lockid_t::NUMLEVELS-1];
00552 public:
00553 void SetDefaultEscalationThresholds();
00554
00555 void ClearAllStoresToFree();
00556 void FreeAllStoresToFree();
00557 rc_t PrepareLogAllStoresToFree();
00558 void DumpStoresToFree();
00559 rc_t ConvertAllLoadStoresToRegularStores();
00560 void ClearAllLoadStores();
00561
00562 ostream & dump_locks(ostream &) const;
00563
00564
00565 private:
00566
00567
00568
00569
00570
00571 static void xct_stats(
00572 u_long& begins,
00573 u_long& commits,
00574 u_long& aborts,
00575 bool reset);
00576
00577 w_rc_t _flush_logbuf();
00578 w_rc_t _sync_logbuf(bool block=true);
00579 void _teardown(bool is_chaining);
00580
00581 #if defined(USE_BLOCK_ALLOC_FOR_XCT_IMPL) && (USE_BLOCK_ALLOC_FOR_XCT_IMPL==1)
00582 public:
00583 #else
00584 private:
00585 #endif
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 struct xct_core
00598 {
00599 xct_core(tid_t const &t, state_t s, timeout_in_ms timeout);
00600 ~xct_core();
00601
00602
00603 tid_t _tid;
00604 timeout_in_ms _timeout;
00605 bool _warn_on;
00606 xct_lock_info_t* _lock_info;
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 bool _lock_cache_enable;
00617
00618
00619
00620
00621 queue_based_lock_t _1thread_xct;
00622
00623
00624
00625 volatile int _updating_operations;
00626
00627
00628 volatile int _threads_attached;
00629
00630
00631 pthread_cond_t _waiters_cond;
00632 mutable pthread_mutex_t _waiters_mutex;
00633
00634 state_t _state;
00635 bool _forced_readonly;
00636 vote_t _vote;
00637 gtid_t * _global_tid;
00638 server_handle_t* _coord_handle;
00639 bool _read_only;
00640
00641
00642
00643
00644
00645 w_list_t<stid_list_elem_t,queue_based_lock_t> _storesToFree;
00646
00647
00648
00649
00650
00651 w_list_t<stid_list_elem_t,queue_based_lock_t> _loadStores;
00652
00653 volatile int _xct_ended;
00654 bool _xct_aborting;
00655
00656 };
00657
00658 private:
00659
00660
00661
00662
00663
00664
00665 mutable queue_based_lock_t _1thread_log;
00666
00667 lsn_t _first_lsn;
00668 lsn_t _last_lsn;
00669 lsn_t _undo_nxt;
00670
00671
00672
00673 w_list_t<xct_dependent_t,queue_based_lock_t> _dependent_list;
00674
00675
00676
00677
00678 static lockid_t::name_space_t convert(concurrency_t cc);
00679 static concurrency_t convert(lockid_t::name_space_t n);
00680
00681
00682
00683
00684 logrec_t* _last_log;
00685 logrec_t* _log_buf;
00686
00687
00688
00689
00690 fileoff_t _log_bytes_rsvd;
00691 fileoff_t _log_bytes_ready;
00692 fileoff_t _log_bytes_used;
00693 fileoff_t _log_bytes_used_fwd;
00694
00695
00696 fileoff_t _log_bytes_reserved_space;
00697
00698 bool _rolling_back;
00699
00700
00701
00702 bool should_consume_rollback_resv(int t) const;
00703 bool should_reserve_for_rollback(int t)
00704 const {
00705 return ! should_consume_rollback_resv(t);
00706 }
00707 private:
00708 volatile int _in_compensated_op;
00709
00710
00711 lsn_t _anchor;
00712
00713
00714 xct_core* _core;
00715
00716 public:
00717 bool rolling_back() const { return _rolling_back; }
00718 #if W_DEBUG_LEVEL > 2
00719 private:
00720 bool _had_error;
00721 public:
00722
00723
00724 void set_error_encountered() { _had_error = true; }
00725 bool error_encountered() const {
00726 return _had_error; }
00727 #else
00728 void set_error_encountered() {}
00729 bool error_encountered() const { return false; }
00730 #endif
00731 tid_t tid() const {
00732 w_assert1(_tid == _core->_tid);
00733 return _tid; }
00734 };
00735
00736
00737
00738
00739 class auto_release_anchor_t {
00740 bool _compensate;
00741 xct_t* _xct;
00742 public:
00743 auto_release_anchor_t (bool and_compensate) :
00744 _compensate(and_compensate), _xct(xct())
00745 {}
00746 ~auto_release_anchor_t ()
00747 {
00748 _xct->release_anchor(_compensate X_LOG_COMMENT_USE("auto_release_anchor_t"));
00749 }
00750 };
00751
00752
00753 class auto_rollback_t {
00754 private:
00755 xct_t* _xd;
00756 lsn_t _save_pt;
00757 bool _roll;
00758 static int _count;
00759 int _test;
00760 int _line;
00761 const char *_file;
00762 public:
00763
00764
00765 w_rc_t test(int x) { _test=x;
00766 if(_test && (_count % _test==0))
00767 return RC(smlevel_0::eOUTOFLOGSPACE);
00768 return RCOK;
00769 }
00770
00771 #define AUTO_ROLLBACK_work auto_rollback_t work(__LINE__, __FILE__);
00772 auto_rollback_t(int line, const char *file)
00773 : _xd(xct()), _roll(true), _test(0),
00774 _line(line), _file(file)
00775 {
00776
00777 _count++;
00778 if(_xd) {
00779
00780 W_COERCE(_xd->save_point(_save_pt));
00781 }
00782 }
00783 void ok() { _roll = false; }
00784
00785 ~auto_rollback_t() {
00786
00787 if(_test && (_count % _test==0)) _roll = true;
00788 if(_roll && _xd) {
00789 _xd->set_error_encountered();
00790 W_COERCE(_xd->rollback(_save_pt));
00791 INC_TSTAT(internal_rollback_cnt);
00792 #if 0 && W_DEBUG_LEVEL > 0
00793 cerr << "Internal rollback to " << _save_pt
00794 << " from " << _line
00795 << " " << _file
00796 << endl;
00797 #endif
00798 }
00799 }
00800 };
00801
00802
00803
00804
00805
00806
00807 #if X_LOG_COMMENT_ON
00808 #define X_DO1(x,anchor,line) \
00809 { \
00810 w_rc_t __e = (x); \
00811 if (__e.is_error()) { \
00812 w_assert3(xct()); \
00813 W_COERCE(xct()->rollback(anchor)); \
00814 xct()->release_anchor(true X_LOG_COMMENT_USE("X_DO1")); \
00815 return RC_AUGMENT(__e); \
00816 } \
00817 }
00818 #define to_string(x) # x
00819 #define X_DO(x,anchor) X_DO1(x,anchor, to_string(x))
00820
00821 #else
00822
00823 #define X_DO(x,anchor) \
00824 { \
00825 w_rc_t __e = (x); \
00826 if (__e.is_error()) { \
00827 w_assert3(xct()); \
00828 W_COERCE(xct()->rollback(anchor)); \
00829 xct()->release_anchor(true X_LOG_COMMENT_USE("X_DO")); \
00830 return RC_AUGMENT(__e); \
00831 } \
00832 }
00833 #endif
00834
00835
00836 class xct_log_switch_t : public smlevel_0 {
00837
00838
00839
00840
00841 switch_t old_state;
00842 public:
00843
00844 NORET xct_log_switch_t(switch_t s) : old_state(OFF)
00845 {
00846 if(smlevel_1::log) {
00847 INC_TSTAT(log_switches);
00848 if (xct()) {
00849 old_state = xct()->set_log_state(s);
00850 }
00851 }
00852 }
00853
00854 NORET
00855 ~xct_log_switch_t() {
00856 if(smlevel_1::log) {
00857 if (xct()) {
00858 xct()->restore_log_state(old_state);
00859 }
00860 }
00861 }
00862 };
00863
00864 inline
00865 bool xct_t::is_log_on() const {
00866 return (me()->xct_log()->xct_log_is_off() == false);
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 class xct_i {
00881 public:
00882
00883
00884
00885
00886
00887
00888
00889 bool locked_by_me() const {
00890 if(xct_t::xlist_mutex_is_mine()) {
00891 W_IFDEBUG1(if(_may_check) w_assert1(_locked);)
00892 return true;
00893 }
00894 return false;
00895 }
00896
00897
00898 void never_mind() {
00899
00900
00901 if(_locked && locked_by_me()) {
00902 *(const_cast<bool *>(&_locked)) = false;
00903 xct_t::release_xlist_mutex();
00904 }
00905 }
00906
00907 xct_t* curr() const { return unsafe_iterator.curr(); }
00908
00909 xct_t* next() { return unsafe_iterator.next(); }
00910
00911
00912
00913 static bool init_locked(bool lockit)
00914 {
00915 if(lockit) {
00916 W_COERCE(xct_t::acquire_xlist_mutex());
00917 }
00918 return lockit;
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928 NORET xct_i(bool locked_accesses)
00929 : _locked(init_locked(locked_accesses)),
00930 _may_check(locked_accesses),
00931 unsafe_iterator(xct_t::_xlist)
00932 {
00933 w_assert1(_locked == locked_accesses);
00934 _check(_locked);
00935 }
00936
00937
00938 NORET ~xct_i() {
00939 if(locked_by_me()) {
00940 _check(true);
00941 never_mind();
00942 _check(false);
00943 }
00944 }
00945
00946 private:
00947 void _check(bool b) const {
00948 if(!_may_check) return;
00949 if(b) xct_t::assert_xlist_mutex_is_mine();
00950 else xct_t::assert_xlist_mutex_not_mine();
00951 }
00952
00953 const bool _locked;
00954 const bool _may_check;
00955 w_list_i<xct_t,queue_based_lock_t> unsafe_iterator;
00956
00957
00958 xct_i(const xct_i&);
00959 xct_i& operator=(const xct_i&);
00960 };
00961
00962
00963
00964 inline
00965 xct_t::state_t
00966 xct_t::state() const
00967 {
00968 return _core->_state;
00969 }
00970
00971
00972
00973
00974 class xct_auto_abort_t : public smlevel_1 {
00975 public:
00976 xct_auto_abort_t() : _xct(xct_t::new_xct()) {
00977 (void) _xct->attach_update_thread();
00978 }
00979 ~xct_auto_abort_t() {
00980 switch(_xct->state()) {
00981 case smlevel_1::xct_ended:
00982
00983 break;
00984 case smlevel_1::xct_active:
00985 case smlevel_1::xct_freeing_space:
00986 case smlevel_1::xct_committing:
00987 W_COERCE(_xct->abort());
00988 break;
00989 default:
00990 cerr << "unexpected xct state: " << _xct->state() << endl;
00991 W_FATAL(eINTERNAL);
00992 }
00993 (void) _xct->detach_update_thread();
00994 xct_t::destroy_xct(_xct);
00995 }
00996 rc_t commit() {
00997
00998
00999 W_DO(_xct->commit());
01000 return RCOK;
01001 }
01002 rc_t abort() {W_DO(_xct->abort()); return RCOK;}
01003
01004 private:
01005 xct_t* _xct;
01006 };
01007
01008
01009 inline
01010 bool
01011 operator>(const xct_t& x1, const xct_t& x2)
01012 {
01013 return (x1.tid() > x2.tid());
01014 }
01015
01016 inline void
01017 xct_t::SetEscalationThresholds(w_base_t::int4_t toPage,
01018 w_base_t::int4_t toStore,
01019 w_base_t::int4_t toVolume)
01020 {
01021 if (toPage != dontModifyThreshold)
01022 escalationThresholds[2] = toPage;
01023
01024 if (toStore != dontModifyThreshold)
01025 escalationThresholds[1] = toStore;
01026
01027 if (toVolume != dontModifyThreshold)
01028 escalationThresholds[0] = toVolume;
01029 }
01030
01031 inline void
01032 xct_t::SetDefaultEscalationThresholds()
01033 {
01034 SetEscalationThresholds(smlevel_0::defaultLockEscalateToPageThreshold,
01035 smlevel_0::defaultLockEscalateToStoreThreshold,
01036 smlevel_0::defaultLockEscalateToVolumeThreshold);
01037 }
01038
01039 inline void
01040 xct_t::GetEscalationThresholds(w_base_t::int4_t &toPage,
01041 w_base_t::int4_t &toStore,
01042 w_base_t::int4_t &toVolume)
01043 {
01044 toPage = escalationThresholds[2];
01045 toStore = escalationThresholds[1];
01046 toVolume = escalationThresholds[0];
01047 }
01048
01049 inline const w_base_t::int4_t *
01050 xct_t::GetEscalationThresholdsArray()
01051 {
01052 return escalationThresholds;
01053 }
01054
01055 inline
01056 xct_t::vote_t
01057 xct_t::vote() const
01058 {
01059 return _core->_vote;
01060 }
01061
01062 inline
01063 const lsn_t&
01064 xct_t::last_lsn() const
01065 {
01066 return _last_lsn;
01067 }
01068
01069 inline
01070 void
01071 xct_t::set_last_lsn( const lsn_t&l)
01072 {
01073 _last_lsn = l;
01074 }
01075
01076 inline
01077 const lsn_t&
01078 xct_t::first_lsn() const
01079 {
01080 return _first_lsn;
01081 }
01082
01083 inline
01084 void
01085 xct_t::set_first_lsn(const lsn_t &l)
01086 {
01087 _first_lsn = l;
01088 }
01089
01090 inline
01091 const lsn_t&
01092 xct_t::undo_nxt() const
01093 {
01094 return _undo_nxt;
01095 }
01096
01097 inline
01098 void
01099 xct_t::set_undo_nxt(const lsn_t &l)
01100 {
01101 _undo_nxt = l;
01102 }
01103
01104 inline
01105 const logrec_t*
01106 xct_t::last_log() const
01107 {
01108 return _last_log;
01109 }
01110
01111 inline
01112 bool
01113 xct_t::forced_readonly() const
01114 {
01115 return _core->_forced_readonly;
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 inline bool
01128 xct_t::is_extern2pc()
01129 const
01130 {
01131
01132 return _core->_global_tid != 0;
01133 }
01134
01135
01136 inline
01137 const gtid_t*
01138 xct_t::gtid() const
01139 {
01140 return _core->_global_tid;
01141 }
01142
01143
01144
01145
01146
01147 #endif