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 > 4
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  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  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 };
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 private:
00195     struct xct_core;            
00196     NORET                        xct_t(
00197         xct_core*                     core,
00198         sm_stats_info_t*             stats,  
00199         const lsn_t&                 last_lsn,
00200         const lsn_t&                 undo_nxt);
00201     NORET                       ~xct_t();
00202 
00203 public:
00204 
00205     friend ostream&             operator<<(ostream&, const xct_t&);
00206 
00207     static int                  collect(vtable_t&, bool names_too);
00208     void                        vtable_collect(vtable_row_t &);
00209     static void                 vtable_collect_names(vtable_row_t &);
00210 
00211     state_t                     state() const;
00212     void                        set_timeout(timeout_in_ms t) ;
00213 
00214     timeout_in_ms               timeout_c() const;
00215 
00216     
00217 
00218 
00219 public:
00220     void                         force_readonly();
00221     bool                         forced_readonly() const;
00222 
00223     vote_t                       vote() const;
00224     bool                         is_extern2pc() const;
00225     rc_t                         enter2pc(const gtid_t &g);
00226     const gtid_t*                gtid() const;
00227     const server_handle_t&       get_coordinator()const; 
00228     void                         set_coordinator(const server_handle_t &); 
00229     static rc_t                  recover2pc(const gtid_t &g,
00230                                  bool mayblock, xct_t *&);  
00231     static rc_t                  query_prepared(int &numtids);
00232     static rc_t                  query_prepared(int numtids, gtid_t l[]);
00233 
00234     rc_t                         prepare();
00235     rc_t                         log_prepared(bool in_chkpt=false);
00236 
00237     
00238 
00239 
00240 public:
00241     static void                 dump(ostream &o); 
00242     static int                  cleanup(bool dispose_prepared=false); 
00243                                  
00244 
00245 
00246     bool                        is_instrumented() {
00247                                    return (__stats != 0);
00248                                 }
00249     void                        give_stats(sm_stats_info_t* s) {
00250                                     w_assert1(__stats == 0);
00251                                     __stats = s;
00252                                 }
00253     void                        clear_stats() {
00254                                     memset(__stats,0, sizeof(*__stats)); 
00255                                 }
00256     sm_stats_info_t*            steal_stats() {
00257                                     sm_stats_info_t*s = __stats; 
00258                                     __stats = 0;
00259                                     return         s;
00260                                 }
00261     const sm_stats_info_t&      const_stats_ref() { return *__stats; }
00262     rc_t                        commit(bool lazy = false, lsn_t* plastlsn=NULL);
00263     rc_t                        rollback(const lsn_t &save_pt);
00264     rc_t                        save_point(lsn_t& lsn);
00265     rc_t                        chain(bool lazy = false);
00266     rc_t                        abort(bool save_stats = false);
00267 
00268     
00269 protected:
00270     sm_stats_info_t&            stats_ref() { return *__stats; }
00271     rc_t                        dispose();
00272     void                        change_state(state_t new_state);
00273     void                        set_first_lsn(const lsn_t &) ;
00274     void                        set_last_lsn(const lsn_t &) ;
00275     void                        set_undo_nxt(const lsn_t &) ;
00276     void                        prepare_restore_log_resv(int, int, int, int);
00277 
00278 
00279 public:
00280 
00281     
00282     const lsn_t&                last_lsn() const;
00283     const lsn_t&                first_lsn() const;
00284     const lsn_t&                undo_nxt() const;
00285     const logrec_t*             last_log() const;
00286     fileoff_t                   get_log_space_used() const;
00287     rc_t                        wait_for_log_space(fileoff_t amt);
00288     
00289     
00290     static xct_t*               look_up(const tid_t& tid);
00291     static tid_t                oldest_tid();        
00292     static tid_t                youngest_tid();        
00293 
00294     static void                 update_youngest_tid(const tid_t &);
00295 
00296 
00297     
00298     static w_base_t::uint4_t    num_active_xcts();
00299 
00300 
00301     
00302     const lsn_t&                anchor(bool grabit = true);
00303     void                        release_anchor(bool compensate
00304                                    ADD_LOG_COMMENT_SIG
00305                                    );
00306     int                         compensated_op_depth() const ;
00307 
00308     
00309     
00310     
00311     
00312     
00313     
00314     
00315     
00316     
00317     
00318 
00319     void                        start_crit() { (void) anchor(false); }
00320     
00321     
00322     
00323     
00324 
00325     void                        stop_crit() {(void) release_anchor(false
00326                                             LOG_COMMENT_USE( "stopcrit"));}
00327     
00328     
00329     void                        compensate(const lsn_t&, 
00330                                           bool undoable
00331                                           ADD_LOG_COMMENT_SIG
00332                                           );
00333     
00334     void                        compensate_undo(const lsn_t&);
00335 
00336 
00337     
00338     
00339     
00340     
00341     
00342     void                         log_warn_disable();
00343     void                         log_warn_resume();
00344     bool                         log_warn_is_on() const;
00345 
00346 
00347 
00348 public:
00349     
00350     rc_t                        add_dependent(xct_dependent_t* dependent);
00351     rc_t                        remove_dependent(xct_dependent_t* dependent);
00352     bool                        find_dependent(xct_dependent_t* dependent);
00353 
00354     
00355     
00356     
00357     bool                        is_log_on() const;
00358     rc_t                        get_logbuf(logrec_t*&, const page_p *p = 0);
00359     rc_t                        give_logbuf(logrec_t*, const page_p *p = 0);
00360 
00361     
00362     
00363     
00364     void                        AddStoreToFree(const stid_t& stid);
00365     void                        AddLoadStore(const stid_t& stid);
00366     
00367     void                        set_alloced() { }
00368 
00369     void                        num_extents_marked_for_deletion(
00370                                         base_stat_t &num);
00371 public:
00372     
00373     void                        GetEscalationThresholds(
00374                                         w_base_t::int4_t &toPage, 
00375                                         w_base_t::int4_t &toStore, 
00376                                         w_base_t::int4_t &toVolume);
00377     void                        SetEscalationThresholds(
00378                                         w_base_t::int4_t toPage,
00379                                         w_base_t::int4_t toStore, 
00380                                         w_base_t::int4_t toVolume);
00381     bool                        set_lock_cache_enable(bool enable);
00382     bool                        lock_cache_enabled();
00383 
00384 protected:
00385 
00386     
00387     
00388     
00389     static lockid_t*            new_lock_hierarchy();
00390     static sdesc_cache_t*       new_sdesc_cache_t();
00391     static xct_log_t*           new_xct_log_t();
00392     void                        steal(lockid_t*&, sdesc_cache_t*&, xct_log_t*&);
00393     void                        stash(lockid_t*&, sdesc_cache_t*&, xct_log_t*&);
00394 
00395     void                        attach_thread(); 
00396     void                        detach_thread(); 
00397 
00398 
00399     
00400     lockid_t*                   lock_info_hierarchy() const {
00401                                     return me()->lock_hierarchy();
00402                                 }
00403 public:
00404     
00405     sdesc_cache_t*              sdesc_cache() const;
00406 
00407 protected:
00408     
00409 
00410     switch_t                    set_log_state(switch_t s);
00411 
00412     void                        restore_log_state(switch_t s);
00413 
00414 
00415 public:
00416     concurrency_t                get_lock_level(); 
00417     void                         lock_level(concurrency_t l);
00418 
00419     int                          num_threads();          
00420     rc_t                         check_one_thread_attached() const;   
00421     void                         attach_update_thread();
00422     void                         detach_update_thread();
00423     int                          update_threads() const;
00424 
00425 protected:
00426     
00427     w_rc_t                       lockblock(timeout_in_ms timeout);
00428     void                         lockunblock(); 
00429     const w_base_t::int4_t*      GetEscalationThresholdsArray();
00430 
00431     rc_t                         check_lock_totals(int nex, 
00432                                         int nix, int nsix, int ) const;
00433     rc_t                         obtain_locks(lock_mode_t mode, 
00434                                         int nlks, const lockid_t *l); 
00435     rc_t                         obtain_one_lock(lock_mode_t mode, 
00436                                         const lockid_t &l); 
00437 
00438     xct_lock_info_t*             lock_info() const;
00439 
00440 public:
00441     
00442     
00443     
00444     static w_rc_t                acquire_xlist_mutex();
00445     static void                  release_xlist_mutex();
00446     static void                  assert_xlist_mutex_not_mine();
00447     static void                  assert_xlist_mutex_is_mine();
00448     static bool                  xlist_mutex_is_mine();
00449 
00450     
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463     void                         force_nonblocking();
00464 
00465 
00466 
00467 
00468 
00469 protected:
00470     
00471     w_link_t                      _xlink;
00472     static w_descend_list_t<xct_t, queue_based_lock_t, tid_t> _xlist;
00473     void                         put_in_order();
00474 private:
00475     static queue_based_lock_t    _xlist_mutex;
00476 
00477     sm_stats_info_t*             __stats; 
00478     lockid_t*                    __saved_lockid_t;
00479     sdesc_cache_t*                __saved_sdesc_cache_t;
00480     xct_log_t*                   __saved_xct_log_t;
00481 
00482     static tid_t                 _nxt_tid;
00483                                         
00484     static tid_t                 _oldest_tid;
00485     
00486     
00487     
00488     tid_t                        _tid;
00489 
00490 public:
00491     void                         acquire_1thread_xct_mutex() const; 
00492     void                         release_1thread_xct_mutex() const; 
00493     bool                         is_1thread_log_mutex_mine() const; 
00494 
00495 
00496 private:
00497     void                         acquire_1thread_log_mutex();
00498     void                         release_1thread_log_mutex();
00499     void                         assert_1thread_log_mutex_free()const;
00500 private:
00501     bool                         is_1thread_xct_mutex_mine() const;
00502     void                         assert_1thread_xct_mutex_free()const;
00503 
00504     rc_t                         _abort();
00505     rc_t                         _commit(w_base_t::uint4_t flags,
00506                                                  lsn_t* plastlsn=NULL);
00507 
00508 protected:
00509     
00510     switch_t                    set_log_state(switch_t s, bool &nested);
00511     void                        restore_log_state(switch_t s, bool nested);
00512 
00513 private:
00514     bool                        one_thread_attached() const;   
00515     
00516     void                        _compensate(const lsn_t&, bool undoable = false);
00517 
00518     w_base_t::int4_t            escalationThresholds[lockid_t::NUMLEVELS-1];
00519 public:
00520     void                        SetDefaultEscalationThresholds();
00521 
00522     void                        ClearAllStoresToFree();
00523     void                        FreeAllStoresToFree();
00524     rc_t                        PrepareLogAllStoresToFree();
00525     void                        DumpStoresToFree();
00526     rc_t                        ConvertAllLoadStoresToRegularStores();
00527     void                        ClearAllLoadStores();
00528 
00529     ostream &                   dump_locks(ostream &) const;
00530 
00531 
00532 private:
00533 
00534     
00535     
00536     
00537 
00538     static void                 xct_stats(
00539                                     u_long&             begins,
00540                                     u_long&             commits,
00541                                     u_long&             aborts,
00542                                     bool                 reset);
00543 
00544     w_rc_t                     _flush_logbuf();
00545     w_rc_t                     _sync_logbuf(bool block=true);
00546     void                       _teardown(bool is_chaining);
00547 
00548 private:
00549     
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560     struct xct_core
00561     {
00562         xct_core(tid_t const &t, state_t s, timeout_in_ms timeout);
00563         ~xct_core();
00564 
00565         
00566         tid_t                  _tid;
00567         timeout_in_ms          _timeout; 
00568         bool                   _warn_on;
00569         xct_lock_info_t*       _lock_info;
00570 
00571         
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579         bool                   _lock_cache_enable;
00580         
00581         
00582         
00583         
00584         queue_based_lock_t     _1thread_xct;
00585         
00586         
00587         
00588         volatile int           _updating_operations; 
00589 
00590         
00591         volatile int           _threads_attached; 
00592 
00593         
00594         pthread_cond_t            _waiters_cond;  
00595         mutable pthread_mutex_t   _waiters_mutex;  
00596 
00597         state_t                   _state;
00598         bool                      _forced_readonly;
00599         vote_t                    _vote;
00600         gtid_t *                  _global_tid; 
00601         server_handle_t*          _coord_handle; 
00602         bool                      _read_only;
00603 
00604         
00605 
00606 
00607 
00608         w_list_t<stid_list_elem_t,queue_based_lock_t>    _storesToFree;
00609 
00610         
00611 
00612 
00613 
00614         w_list_t<stid_list_elem_t,queue_based_lock_t>    _loadStores;
00615 
00616         volatile int      _xct_ended; 
00617     };
00618     
00619 private: 
00620     
00621     
00622     
00623 
00624     
00625     
00626     mutable queue_based_lock_t   _1thread_log;
00627 
00628     lsn_t                        _first_lsn;
00629     lsn_t                        _last_lsn;
00630     lsn_t                        _undo_nxt;
00631 
00632     
00633     
00634     w_list_t<xct_dependent_t,queue_based_lock_t>    _dependent_list;
00635 
00636     
00637 
00638 
00639     static lockid_t::name_space_t    convert(concurrency_t cc);
00640     static concurrency_t             convert(lockid_t::name_space_t n);
00641 
00642     
00643 
00644 
00645     logrec_t*                    _last_log;    
00646     logrec_t*                    _log_buf;
00647 
00648     
00649 
00650  
00651     fileoff_t                    _log_bytes_rsvd; 
00652     fileoff_t                    _log_bytes_ready; 
00653     fileoff_t                    _log_bytes_used; 
00654     fileoff_t                    _log_bytes_reserved_space;
00655                                  
00656     bool                         _rolling_back;
00657                                  
00658                                  
00659 
00660 #if CHECK_NESTING_VARIABLES
00661     
00662     volatile int                 _acquire_1thread_log_depth;  
00663 public:
00664     void inc_acquire_1thread_log_depth() { _acquire_1thread_log_depth ++; }
00665     void dec_acquire_1thread_log_depth() { -- _acquire_1thread_log_depth; }
00666     int  acquire_1thread_log_depth() const { return 
00667                                                _acquire_1thread_log_depth; }
00668 #else
00669 public:
00670     void inc_acquire_1thread_log_depth() { }
00671     void dec_acquire_1thread_log_depth() { }
00672     int  acquire_1thread_log_depth() const { return  0; }
00673 #endif
00674 private:
00675 
00676      volatile int                _in_compensated_op; 
00677         
00678         
00679      lsn_t                       _anchor;
00680         
00681 
00682      xct_core*                   _core;
00683 
00684 public:
00685     tid_t                       tid() const { 
00686                                     w_assert1(_tid == _core->_tid);
00687                                     return _tid; }
00688 };
00689 
00690 
00691 class auto_release_anchor_t {
00692 private:
00693     xct_t* _xd;
00694     lsn_t _anchor;
00695     bool _and_compensate;
00696     int    _line; 
00697 
00698     operator lsn_t const&() const { return _anchor; }
00699 public:
00700 
00701     auto_release_anchor_t(bool and_compensate, int line)
00702         : _xd(xct()), _and_compensate(and_compensate), _line(line)
00703     {
00704     if(_xd)
00705         _anchor = _xd->anchor(_and_compensate);
00706     }
00707     void compensate() {
00708     if(_xd)
00709         _xd->compensate(_anchor, false
00710                 LOG_COMMENT_USE("auto_release_anchor_t")
00711                 );
00712     _xd = 0; 
00713     }
00714     ~auto_release_anchor_t(); 
00715 };
00716 
00717 
00718 
00719 
00720 
00721 #if X_LOG_COMMENT_ON
00722 #define X_DO1(x,anchor,line)             \
00723 {                           \
00724     w_rc_t __e = (x);       \
00725     if (__e.is_error()) {        \
00726         w_assert3(xct());        \
00727         W_COERCE(xct()->rollback(anchor));        \
00728         xct()->release_anchor(true, line );    \
00729         return RC_AUGMENT(__e); \
00730     } \
00731 }
00732 #define to_string(x) # x
00733 #define X_DO(x,anchor) X_DO1(x,anchor, to_string(x))
00734 
00735 #else
00736 
00737 #define X_DO(x,anchor)             \
00738 {                           \
00739     w_rc_t __e = (x);       \
00740     if (__e.is_error()) {        \
00741         w_assert3(xct());        \
00742         W_COERCE(xct()->rollback(anchor));        \
00743         xct()->release_anchor(true);        \
00744         return RC_AUGMENT(__e); \
00745     } \
00746 }
00747 #endif
00748 
00749 
00750 class xct_log_switch_t : public smlevel_0 {
00751     
00752 
00753 
00754 
00755 
00756 
00757 
00758     switch_t old_state;
00759 public:
00760 
00761     NORET xct_log_switch_t(switch_t s)  : old_state(OFF)
00762     {
00763         if(smlevel_1::log) {
00764             INC_TSTAT(log_switches);
00765             if (xct()) {
00766                 old_state = xct()->set_log_state(s);
00767             }
00768         }
00769     }
00770 
00771     NORET
00772     ~xct_log_switch_t()  {
00773         if(smlevel_1::log) {
00774             if (xct()) {
00775                 xct()->restore_log_state(old_state);
00776             }
00777         }
00778     }
00779 };
00780 
00781 inline
00782 bool xct_t::is_log_on() const {
00783     return (me()->xct_log()->xct_log_is_off() == false);
00784 }
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 class xct_i  {
00798 public:
00799     
00800     
00801     
00802     
00803     
00804 
00805 
00806     bool locked_by_me() const {
00807         if(xct_t::xlist_mutex_is_mine()) {
00808             W_IFDEBUG1(if(_may_check) w_assert1(_locked);)
00809             return true;
00810         }
00811         return false;
00812     }
00813 
00814 
00815     void never_mind() {
00816         
00817         
00818         if(_locked && locked_by_me()) {
00819             *(const_cast<bool *>(&_locked)) = false; 
00820             xct_t::release_xlist_mutex();
00821         }
00822     }
00823 
00824     xct_t* curr() const { return unsafe_iterator.curr(); }
00825 
00826     xct_t* next() { return unsafe_iterator.next(); }
00827 
00828 
00829     
00830     static bool init_locked(bool lockit) 
00831     {
00832         if(lockit) {
00833             W_COERCE(xct_t::acquire_xlist_mutex());
00834         }
00835         return lockit;
00836     }
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845     NORET xct_i(bool locked_accesses)
00846         : _locked(init_locked(locked_accesses)),
00847         _may_check(locked_accesses),
00848         unsafe_iterator(xct_t::_xlist)
00849     {
00850         w_assert1(_locked == locked_accesses);
00851         _check(_locked);
00852     }
00853 
00854 
00855     NORET ~xct_i() { 
00856         if(locked_by_me()) {
00857           _check(true);
00858           never_mind(); 
00859           _check(false);
00860         }
00861     }
00862 
00863 private:
00864     void _check(bool b) const  {
00865           if(!_may_check) return;
00866           if(b) xct_t::assert_xlist_mutex_is_mine(); 
00867           else  xct_t::assert_xlist_mutex_not_mine(); 
00868     }
00869     
00870     const bool            _locked;
00871     const bool            _may_check;
00872     w_list_i<xct_t,queue_based_lock_t> unsafe_iterator;
00873 
00874     
00875     xct_i(const xct_i&);
00876     xct_i& operator=(const xct_i&);
00877 };
00878     
00879 
00880 
00881 
00882 
00883 
00884 class xct_auto_abort_t : public smlevel_1 {
00885 public:
00886     xct_auto_abort_t() : _xct(xct_t::new_xct()) {}
00887     ~xct_auto_abort_t() {
00888         switch(_xct->state()) {
00889         case smlevel_1::xct_ended:
00890             
00891             break;
00892         case smlevel_1::xct_active:
00893             W_COERCE(_xct->abort());
00894             break;
00895         default:
00896             W_FATAL(eINTERNAL);
00897         }
00898         xct_t::destroy_xct(_xct);
00899     }
00900     rc_t commit() {
00901         
00902         
00903         W_DO(_xct->commit());
00904         return RCOK;
00905     }
00906     rc_t abort() {W_DO(_xct->abort()); return RCOK;}
00907 
00908 private:
00909     xct_t*        _xct;
00910 };
00911 
00912 inline
00913 xct_t::state_t
00914 xct_t::state() const
00915 {
00916     return _core->_state;
00917 }
00918 
00919 
00920 inline
00921 bool
00922 operator>(const xct_t& x1, const xct_t& x2)
00923 {
00924     return (x1.tid() > x2.tid());
00925 }
00926 
00927 inline void
00928 xct_t::SetEscalationThresholds(w_base_t::int4_t toPage, 
00929                 w_base_t::int4_t toStore, 
00930                 w_base_t::int4_t toVolume)
00931 {
00932     if (toPage != dontModifyThreshold)
00933                 escalationThresholds[2] = toPage;
00934     
00935     if (toStore != dontModifyThreshold)
00936                 escalationThresholds[1] = toStore;
00937     
00938     if (toVolume != dontModifyThreshold)
00939                 escalationThresholds[0] = toVolume;
00940 }
00941 
00942 inline void
00943 xct_t::SetDefaultEscalationThresholds()
00944 {
00945     SetEscalationThresholds(smlevel_0::defaultLockEscalateToPageThreshold,
00946             smlevel_0::defaultLockEscalateToStoreThreshold,
00947             smlevel_0::defaultLockEscalateToVolumeThreshold);
00948 }
00949 
00950 inline void
00951 xct_t::GetEscalationThresholds(w_base_t::int4_t &toPage, 
00952                 w_base_t::int4_t &toStore, 
00953                 w_base_t::int4_t &toVolume)
00954 {
00955     toPage = escalationThresholds[2];
00956     toStore = escalationThresholds[1];
00957     toVolume = escalationThresholds[0];
00958 }
00959 
00960 inline const w_base_t::int4_t *
00961 xct_t::GetEscalationThresholdsArray()
00962 {
00963     return escalationThresholds;
00964 }
00965 
00966 inline
00967 xct_t::vote_t
00968 xct_t::vote() const
00969 {
00970     return _core->_vote;
00971 }
00972 
00973 inline
00974 const lsn_t&
00975 xct_t::last_lsn() const
00976 {
00977     return _last_lsn;
00978 }
00979 
00980 inline
00981 void
00982 xct_t::set_last_lsn( const lsn_t&l)
00983 {
00984     _last_lsn = l;
00985 }
00986 
00987 inline
00988 const lsn_t&
00989 xct_t::first_lsn() const
00990 {
00991     return _first_lsn;
00992 }
00993 
00994 inline
00995 void
00996 xct_t::set_first_lsn(const lsn_t &l) 
00997 {
00998     _first_lsn = l;
00999 }
01000 
01001 inline
01002 const lsn_t&
01003 xct_t::undo_nxt() const
01004 {
01005     return _undo_nxt;
01006 }
01007 
01008 inline
01009 void
01010 xct_t::set_undo_nxt(const lsn_t &l) 
01011 {
01012     _undo_nxt = l;
01013 }
01014 
01015 inline
01016 const logrec_t*
01017 xct_t::last_log() const
01018 {
01019     return _last_log;
01020 }
01021 
01022 inline
01023 bool
01024 xct_t::forced_readonly() const
01025 {
01026     return _core->_forced_readonly;
01027 }
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 
01037 
01038 inline bool            
01039 xct_t::is_extern2pc() 
01040 const
01041 {
01042     
01043     return _core->_global_tid != 0;
01044 }
01045 
01046 
01047 inline
01048 const gtid_t*           
01049 xct_t::gtid() const 
01050 {
01051     return _core->_global_tid;
01052 }
01053 
01054 
01055 
01056 
01057 
01058 #endif