TAO_Notify::Routing_Slip_Persistence_Manager Class Reference

Manage interaction between Routing_Slip and persistent storage. More...

#include <Routing_Slip_Persistence_Manager.h>

Collaboration diagram for TAO_Notify::Routing_Slip_Persistence_Manager:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_UINT64 Block_Serial_Number
 A unique identifier for logical blocks in persistent storage.

typedef ACE_UINT32 Block_Number
 The physical address of a block in persistent storage.

typedef ACE_UINT16 Block_Size
 The size of a block in persistent storage.

typedef ACE_UINT16 Block_Type
 A code to indicate the type of block in persistent storage.


Public Member Functions

 Routing_Slip_Persistence_Manager (Standard_Event_Persistence_Factory *factory)
 The constructor.

 ~Routing_Slip_Persistence_Manager ()
 The destructor.

void set_callback (Persistent_Callback *callback)
 Set up callbacks.

bool store (const ACE_Message_Block &event, const ACE_Message_Block &routing_slip)
 Store an event + routing slip.

bool update (const ACE_Message_Block &routing_slip)
 Update the routing slip.

bool remove ()
 Remove our associated event and routing slip from the Persistent_File_Allocator.

bool reload (ACE_Message_Block *&event, ACE_Message_Block *&routing_slip)
 Call this method to recover data during event reload.

Routing_Slip_Persistence_Managerload_next ()
 Get next RSPM during reload.

bool store_root ()
 Commit root data to disk, which should only be done for a root node.

bool load (Block_Number block_number, Block_Serial_Number expected_serial_number)
 Reload data into this RSPM from the given block/serial#.

bool is_root () const
 Is this RSPM attached to the root block?

void release_all ()
 During cleanup for shut down, release all chained RSPMs.


Private Member Functions

bool store_i (const ACE_Message_Block &event, const ACE_Message_Block &routing_slip)
bool update_i (const ACE_Message_Block &routing_slip)
bool store_event (const ACE_Message_Block &event)
size_t fill_block (Persistent_Storage_Block &psb, size_t offset_into_block, const ACE_Message_Block *data, size_t offset_into_msg)
size_t fill_block (Persistent_Storage_Block &psb, size_t offset_into_block, unsigned char *data, size_t data_size)
bool build_chain (Persistent_Storage_Block *first_block, Block_Header &first_header, ACE_Unbounded_Stack< size_t > &allocated_blocks, const ACE_Message_Block &data)
 Build a chain of Persistent_Storage_Blocks.

bool reload_chain (Persistent_Storage_Block *first_block, Block_Header &first_header, ACE_Unbounded_Stack< size_t > &allocated_blocks, ACE_Message_Block *amb, ACE_UINT64 expected_serial_number)
 Reload a chain from persistent store.

bool update_next_manager (Routing_Slip_Persistence_Manager *next)
 Locked method to do the work of setting the next_manager_.

bool persisted ()
 Have we been persisted yet?

size_t write_first_routing_slip_block (bool prepare_only=false)
 Write out our first event block.

void dllist_push_back ()
 Insert ourselves into a linked list of Routing_Slip_Persistnce_Managers.

void insert_before (Routing_Slip_Persistence_Manager *node)
void remove_from_dllist ()
 Remove ourselves from a linked list of Routing_Slip_Persistence_Managers.


Private Attributes

ACE_SYNCH_MUTEX lock_
bool removed_
ACE_UINT64 serial_number_
Persistent_File_Allocatorallocator_
Standard_Event_Persistence_Factoryfactory_
Event_Header event_header_
Routing_Slip_Header routing_slip_header_
Persistent_Storage_Blockfirst_event_block_
Persistent_Storage_Blockfirst_routing_slip_block_
Routing_Slip_Persistence_Managerprev_manager_
 We are part of a doubly-linked list.

Routing_Slip_Persistence_Managernext_manager_
ACE_Unbounded_Stack< size_t > allocated_event_blocks_
ACE_Unbounded_Stack< size_t > allocated_routing_slip_blocks_
Persistent_Callbackcallback_
ACE_Message_Blockevent_mb_
 if these are non-zero we own 'em

ACE_Message_Blockrouting_slip_mb_

Detailed Description

Manage interaction between Routing_Slip and persistent storage.

todo: to complete the strategization of event persistent storage this should become an interface that is implemented differently by different strategies. For now it interacts with Standard_Event_Persistence.

Definition at line 49 of file Routing_Slip_Persistence_Manager.h.


Member Typedef Documentation

typedef ACE_UINT32 TAO_Notify::Routing_Slip_Persistence_Manager::Block_Number
 

The physical address of a block in persistent storage.

Definition at line 55 of file Routing_Slip_Persistence_Manager.h.

Referenced by load().

typedef ACE_UINT64 TAO_Notify::Routing_Slip_Persistence_Manager::Block_Serial_Number
 

A unique identifier for logical blocks in persistent storage.

Definition at line 53 of file Routing_Slip_Persistence_Manager.h.

Referenced by load().

typedef ACE_UINT16 TAO_Notify::Routing_Slip_Persistence_Manager::Block_Size
 

The size of a block in persistent storage.

Definition at line 57 of file Routing_Slip_Persistence_Manager.h.

typedef ACE_UINT16 TAO_Notify::Routing_Slip_Persistence_Manager::Block_Type
 

A code to indicate the type of block in persistent storage.

Definition at line 59 of file Routing_Slip_Persistence_Manager.h.

Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::Block_Header().


Constructor & Destructor Documentation

TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Persistence_Manager Standard_Event_Persistence_Factory factory  ) 
 

The constructor.

Definition at line 12 of file Routing_Slip_Persistence_Manager.cpp.

References next_manager_, and prev_manager_.

00014   : removed_(false)
00015   , serial_number_(0)
00016   , allocator_(factory->allocator())
00017   , factory_(factory)
00018   , first_event_block_(0)
00019   , first_routing_slip_block_(0)
00020   , callback_(0)
00021   , event_mb_ (0)
00022   , routing_slip_mb_(0)
00023 {
00024   this->prev_manager_ = this;
00025   this->next_manager_ = this;
00026 }

TAO_Notify::Routing_Slip_Persistence_Manager::~Routing_Slip_Persistence_Manager  ) 
 

The destructor.

Definition at line 28 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, event_mb_, first_event_block_, first_routing_slip_block_, and routing_slip_mb_.

00029 {
00030   ACE_ASSERT(this->prev_manager_ == this);
00031   ACE_ASSERT(this->next_manager_ == this);
00032   delete this->first_event_block_;
00033   this->first_event_block_ = 0;
00034   delete this->first_routing_slip_block_;
00035   this->first_routing_slip_block_ = 0;
00036   delete this->event_mb_;
00037   this->event_mb_ = 0;
00038   delete this->routing_slip_mb_;
00039   this->routing_slip_mb_ = 0;
00040 }


Member Function Documentation

bool TAO_Notify::Routing_Slip_Persistence_Manager::build_chain Persistent_Storage_Block first_block,
Block_Header first_header,
ACE_Unbounded_Stack< size_t > &  allocated_blocks,
const ACE_Message_Block data
[private]
 

Build a chain of Persistent_Storage_Blocks.

Definition at line 554 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_NEW_RETURN, TAO_Notify::Persistent_File_Allocator::allocate(), TAO_Notify::Persistent_Storage_Block::block_number(), ACE_Message_Block::cont(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::data_size, fill_block(), TAO_Notify::Persistent_File_Allocator::free(), ACE_Message_Block::length(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::next_overflow, ACE_Unbounded_Stack< T >::pop(), ACE_Unbounded_Stack< T >::push(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::put_header(), ACE_Message_Block::total_length(), and TAO_Notify::Persistent_File_Allocator::write().

Referenced by store_event(), store_i(), store_root(), and update_i().

00558 {
00559   size_t data_size = data.total_length();
00560   size_t remainder = data_size;
00561   bool result = true;
00562   // Save the number of items currently on the allocation list for
00563   ACE_Unbounded_Stack<size_t> blocks_to_free;
00564   size_t block_number = 0;
00565 
00566   // reverse the order so when we pop, we free up things closer to block 0
00567   // first
00568   while (allocated_blocks.pop(block_number) == 0)
00569   {
00570     blocks_to_free.push(block_number);
00571   }
00572   size_t pos = first_header.put_header(
00573     *first_block);
00574   const ACE_Message_Block* mblk = &data;
00575   remainder = this->fill_block(*first_block, pos, mblk, 0);
00576   while ((remainder == 0) && (mblk->cont() != 0))
00577   {
00578     pos += mblk->length();
00579     mblk = mblk->cont();
00580     remainder = this->fill_block(*first_block, pos, mblk, 0);
00581   }
00582   first_header.data_size = 
00583     static_cast<TAO_Notify::Routing_Slip_Persistence_Manager::Block_Size> (data_size - remainder);
00584   first_header.next_overflow = 0;
00585 
00586   Block_Header* prevhdr = &first_header;
00587   Persistent_Storage_Block* prevblk = first_block;
00588 
00589   while (remainder > 0)
00590   {
00591     Overflow_Header* hdr = 0;
00592     ACE_NEW_RETURN(hdr, Overflow_Header, result);
00593 
00594     Persistent_Storage_Block* curblk = this->allocator_->allocate();
00595     allocated_blocks.push(curblk->block_number());
00596     // Set the previous block's overflow "pointer" to us.
00597     prevhdr->next_overflow = curblk->block_number();
00598     prevhdr->put_header(*prevblk);
00599     pos = hdr->put_header(*curblk);
00600     hdr->data_size = 
00601       static_cast<TAO_Notify::Routing_Slip_Persistence_Manager::Block_Size> (remainder);
00602 
00603     size_t offset_into_msg = mblk->length() - remainder;
00604     remainder = this->fill_block(*curblk, pos, mblk, offset_into_msg);
00605     while ((remainder == 0) && (mblk->cont() != 0))
00606     {
00607       pos += mblk->length();
00608       mblk = mblk->cont();
00609       remainder = this->fill_block(*curblk, pos, mblk, 0);
00610     }
00611 
00612     hdr->data_size = hdr->data_size - 
00613       static_cast<TAO_Notify::Routing_Slip_Persistence_Manager::Block_Size> (remainder);
00614     if (prevblk != first_block)
00615     {
00616       // allocator obtains ownership, so write out and delete the header
00617       // only.
00618       result &= this->allocator_->write(prevblk);
00619       delete prevhdr;
00620     }
00621     prevblk = curblk;
00622     prevhdr = hdr;
00623   }
00624   if (prevblk != first_block)
00625   {
00626     prevhdr->put_header(*prevblk);
00627     result &= this->allocator_->write(prevblk);
00628     delete prevhdr;
00629   }
00630   pos = first_header.put_header(
00631     *first_block);
00632   // Free all but the first routing_slip_block
00633   while (blocks_to_free.pop(block_number) == 0)
00634   {
00635     this->allocator_->free(block_number);
00636   }
00637 
00638   return result;
00639 }

void TAO_Notify::Routing_Slip_Persistence_Manager::dllist_push_back  )  [private]
 

Insert ourselves into a linked list of Routing_Slip_Persistnce_Managers.

Definition at line 769 of file Routing_Slip_Persistence_Manager.cpp.

References insert_before().

Referenced by load_next(), and store_i().

00770 {
00771   insert_before (&this->factory_->root());
00772 }

size_t TAO_Notify::Routing_Slip_Persistence_Manager::fill_block Persistent_Storage_Block psb,
size_t  offset_into_block,
unsigned char *  data,
size_t  data_size
[private]
 

Definition at line 531 of file Routing_Slip_Persistence_Manager.cpp.

References TAO_Notify::Persistent_File_Allocator::block_size(), TAO_Notify::Persistent_Storage_Block::data(), and ACE_OS::memcpy().

00533 {
00534   size_t result = 0;
00535   if (data_size > 0)
00536   {
00537     const size_t max_size = this->allocator_->block_size() - offset_into_block;
00538     size_t size_to_copy = data_size;
00539     if (size_to_copy > max_size)
00540     {
00541       size_to_copy = max_size;
00542       result = data_size - size_to_copy;
00543     }
00544     else
00545     {
00546       result = 0;
00547     }
00548     ACE_OS::memcpy(psb.data() + offset_into_block, data, size_to_copy);
00549   }
00550   return result;
00551 }

size_t TAO_Notify::Routing_Slip_Persistence_Manager::fill_block Persistent_Storage_Block psb,
size_t  offset_into_block,
const ACE_Message_Block data,
size_t  offset_into_msg
[private]
 

Fill in a block with data, and return the number of bytes of data remaining to be written.

Definition at line 521 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_Message_Block::length(), and ACE_Message_Block::rd_ptr().

Referenced by build_chain().

00524 {
00525   unsigned char* ptr = (unsigned char*)data->rd_ptr();
00526   return this->fill_block(psb, offset_into_block, ptr + offset_into_msg,
00527   data->length() - offset_into_msg);
00528 }

void TAO_Notify::Routing_Slip_Persistence_Manager::insert_before Routing_Slip_Persistence_Manager node  )  [private]
 

Definition at line 775 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, next_manager_, and prev_manager_.

Referenced by dllist_push_back().

00776 {
00777   // Since this is a private function, the caller should have done locking
00778   // on the factory before calling here.  The same is true for removals.
00779   ACE_ASSERT(this->prev_manager_ == this);
00780   ACE_ASSERT(this->next_manager_ == this);
00781   ACE_ASSERT(node != this);
00782   this->prev_manager_ = node->prev_manager_;
00783   node->prev_manager_ = this;
00784   this->next_manager_ = node;
00785   this->prev_manager_->next_manager_ = this;
00786 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::is_root  )  const
 

Is this RSPM attached to the root block?

Definition at line 737 of file Routing_Slip_Persistence_Manager.cpp.

References serial_number_.

Referenced by release_all().

00738 {
00739   return this->serial_number_ == ROUTING_SLIP_ROOT_SERIAL_NUMBER;
00740 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::load Block_Number  block_number,
Block_Serial_Number  expected_serial_number
 

Reload data into this RSPM from the given block/serial#.

Returns:
false if the reload is not successful.

NOTE: There is no need to worry about guarding anything. We assume that there will be one and only one thread doing the entire reload process.

Definition at line 110 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ERROR, ACE_NEW_NORETURN, ACE_TEXT, TAO_Notify::Persistent_File_Allocator::allocate_at(), Block_Number, Block_Serial_Number, TAO_Notify::Persistent_File_Allocator::block_size(), TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::event_block, event_mb_, first_event_block_, first_routing_slip_block_, LM_ERROR, reload_chain(), routing_slip_header_, routing_slip_mb_, serial_number_, TAO_Notify::Persistent_Storage_Block::set_allocator_owns(), and TAO_Notify::Persistent_Storage_Block::set_sync().

Referenced by load_next(), and TAO_Notify::Standard_Event_Persistence_Factory::open().

00113 {
00114   /**
00115    * NOTE: There is no need to worry about guarding anything.  We assume
00116    *       that there will be one and only one thread doing the entire
00117    *       reload process.
00118    */
00119   bool result = false;
00120   size_t block_size = this->allocator_->block_size();
00121   this->first_routing_slip_block_ =
00122     this->allocator_->allocate_at(block_number);
00123   this->first_routing_slip_block_->set_allocator_owns(false);
00124   this->first_routing_slip_block_->set_sync();
00125 
00126   this->serial_number_ = expected_serial_number;
00127 
00128   ACE_NEW_NORETURN(this->routing_slip_mb_, ACE_Message_Block(block_size));
00129   ACE_NEW_NORETURN(this->event_mb_, ACE_Message_Block(block_size));
00130   if (this->event_mb_ != 0 && this->routing_slip_mb_ != 0)
00131   {
00132     if (this->reload_chain(
00133           this->first_routing_slip_block_,
00134           this->routing_slip_header_,
00135           this->allocated_routing_slip_blocks_,
00136           this->routing_slip_mb_,
00137           expected_serial_number))
00138     {
00139       if (this->routing_slip_header_.event_block != 0)
00140       {
00141         this->first_event_block_ = this->allocator_->allocate_at(
00142           this->routing_slip_header_.event_block);
00143         result = this->reload_chain(
00144           this->first_event_block_,
00145           this->event_header_,
00146           this->allocated_event_blocks_,
00147           this->event_mb_,
00148           0);
00149       }
00150       else if (block_number == ROUTING_SLIP_ROOT_BLOCK_NUMBER)
00151       {
00152         // only the root can lack event
00153         result = true;
00154       }
00155       else
00156       {
00157         ACE_ERROR((LM_ERROR,
00158           ACE_TEXT(
00159             "(%P|%t) Reloaded Persistent Event is missing event.\n")
00160           ));
00161       }
00162     }
00163   }
00164   if (! result)
00165   {
00166     delete this->routing_slip_mb_;
00167     this->routing_slip_mb_ = 0;
00168     delete this->event_mb_;
00169     this->event_mb_ = 0;
00170   }
00171   return result;
00172 }

Routing_Slip_Persistence_Manager * TAO_Notify::Routing_Slip_Persistence_Manager::load_next  ) 
 

Get next RSPM during reload.

After using the data from the reload method, call this method to get the next RSPM. It returns a null pointer when all persistent events have been reloaded.

Definition at line 175 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_NEW_RETURN, dllist_push_back(), TAO_Notify::Standard_Event_Persistence_Factory::done_reloading(), first_routing_slip_block_, load(), and serial_number_.

Referenced by TAO_Notify::Standard_Event_Persistence_Factory::first_reload_manager(), and TAO_Notify_EventChannelFactory::load_event_persistence().

00176 {
00177   Routing_Slip_Persistence_Manager * result;
00178   ACE_NEW_RETURN(result, Routing_Slip_Persistence_Manager (this->factory_), 0);
00179 
00180   if (result->load(this->routing_slip_header_.next_routing_slip_block,
00181     this->routing_slip_header_.next_serial_number))
00182   {
00183     result->dllist_push_back();
00184   }
00185   else
00186   {
00187     // steal the psb for use as the next psb.
00188     // delete the rspm.  We'll create another one later.
00189     Persistent_Storage_Block * next_psb = result->first_routing_slip_block_;
00190     result->first_routing_slip_block_ = 0;
00191 //    next_psb->set_allocator_owns(true);
00192     this->factory_->done_reloading (
00193       next_psb,
00194       result->serial_number_);
00195     delete result;
00196     result = 0;
00197   }
00198   return result;
00199 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::persisted  )  [private]
 

Have we been persisted yet?

Definition at line 731 of file Routing_Slip_Persistence_Manager.cpp.

References first_routing_slip_block_.

Referenced by store_i(), and update().

00732 {
00733   return (0 != this->first_routing_slip_block_);
00734 }

void TAO_Notify::Routing_Slip_Persistence_Manager::release_all  ) 
 

During cleanup for shut down, release all chained RSPMs.

Definition at line 743 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, is_root(), next_manager_, and remove_from_dllist().

Referenced by TAO_Notify::Standard_Event_Persistence_Factory::~Standard_Event_Persistence_Factory().

00744 {
00745   ACE_ASSERT(is_root());
00746   while (this->next_manager_ != this)
00747   {
00748     Routing_Slip_Persistence_Manager * next = this->next_manager_;
00749     next->remove_from_dllist();
00750     ACE_ASSERT(next != this->next_manager_);
00751     delete next;
00752   }
00753 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::reload ACE_Message_Block *&  event,
ACE_Message_Block *&  routing_slip
 

Call this method to recover data during event reload.

It should not fail under normal circumstances. Caller owns the resulting message blocks and is responsible for deleting them. Reload the event and routing_slip from the Persistent_File_Allocator.

Definition at line 88 of file Routing_Slip_Persistence_Manager.cpp.

References event_mb_, and routing_slip_mb_.

Referenced by TAO_Notify::Routing_Slip::create().

00091 {
00092   bool result = false;
00093   if (this->event_mb_ != 0 && this->routing_slip_mb_ != 0)
00094   {
00095     event = this->event_mb_;
00096     this->event_mb_ = 0;
00097     routing_slip = this->routing_slip_mb_;
00098     this->routing_slip_mb_ = 0;
00099     result = true;
00100   }
00101   else
00102   {
00103     event = 0;
00104     routing_slip = 0;
00105   }
00106   return result;
00107 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::reload_chain Persistent_Storage_Block first_block,
Block_Header first_header,
ACE_Unbounded_Stack< size_t > &  allocated_blocks,
ACE_Message_Block amb,
ACE_UINT64  expected_serial_number
[private]
 

Reload a chain from persistent store.

Definition at line 642 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_Message_Block, ACE_NEW_RETURN, TAO_Notify::Persistent_File_Allocator::allocate_at(), TAO_Notify::Persistent_Storage_Block::block_number(), TAO_Notify::Persistent_File_Allocator::block_size(), ACE_Message_Block::cont(), TAO_Notify::Persistent_Storage_Block::data(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::data_size, TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::extract_header(), ACE_OS::memcpy(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::next_overflow, ACE_Unbounded_Stack< T >::push(), ACE_Message_Block::rd_ptr(), TAO_Notify::Persistent_File_Allocator::read(), TAO_Notify::Persistent_Storage_Block::reassign_data(), TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::serial_number, and ACE_Message_Block::wr_ptr().

Referenced by load().

00648 {
00649   bool result = false;
00650   size_t block_size = this->allocator_->block_size();
00651   if (this->allocator_->read(first_block))
00652   {
00653     size_t pos = 0;
00654     size_t nextptr = 0;
00655     ACE_Message_Block* mbptr = amb;
00656     ACE_Message_Block* mbnew = 0;
00657 
00658     pos = first_header.extract_header(*first_block);
00659     if (first_header.serial_number == expected_serial_number)
00660     {
00661       // We have to copy the first block because we cache it.
00662       ACE_OS::memcpy(mbptr->wr_ptr(), first_block->data(),
00663         block_size);
00664       mbptr->rd_ptr(pos);
00665       mbptr->wr_ptr(pos + first_header.data_size);
00666       nextptr = first_header.next_overflow;
00667       while (nextptr != 0)
00668       {
00669         Overflow_Header overflow_header;
00670         ACE_NEW_RETURN(mbnew, ACE_Message_Block(block_size), result);
00671         mbptr->cont(mbnew);
00672         Persistent_Storage_Block* psb = this->allocator_->allocate_at(nextptr);
00673         mbptr = mbnew;
00674         // Deallocate the PSB's data and reallocate it to our wr_ptr()...
00675         psb->reassign_data(static_cast<unsigned char*> (static_cast<void*> (mbptr->wr_ptr())), true);
00676         // ...read into the PSB (whose data is inside of the AMB)...
00677         this->allocator_->read(psb);
00678         allocated_blocks.push(psb->block_number());
00679         // ...extract all headers so we know the data's size...
00680         pos = overflow_header.extract_header(*psb);
00681         // ...set up the region that somebody else can look at...
00682         mbptr->rd_ptr(pos);
00683         mbptr->wr_ptr(pos + overflow_header.data_size);
00684         // ...then make sure we don't delete data since we don't own it.
00685         psb->reassign_data(0);
00686         delete psb;
00687         nextptr = overflow_header.next_overflow;
00688       }
00689       result = true;
00690     }
00691   }
00692   return result;
00693 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::remove  ) 
 

Remove our associated event and routing slip from the Persistent_File_Allocator.

Definition at line 231 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, TAO_Notify::Persistent_File_Allocator::allocate_nowrite(), allocated_event_blocks_, allocated_routing_slip_blocks_, first_event_block_, first_routing_slip_block_, TAO_Notify::Persistent_File_Allocator::free(), TAO_Notify::Standard_Event_Persistence_Factory::lock, ACE_Unbounded_Stack< size_t >::pop(), prev_manager_, remove_from_dllist(), TAO_Notify::Persistent_Storage_Block::set_callback(), update_next_manager(), and TAO_Notify::Persistent_File_Allocator::write().

Referenced by TAO_Notify::Routing_Slip::enter_state_deleting().

00232 {
00233   bool result = false;
00234   ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result);
00235   // Assert that this is in the dllist
00236   ACE_ASSERT(this->prev_manager_ != this);
00237   ACE_ASSERT(this->persisted());
00238   Routing_Slip_Persistence_Manager* prev = this->prev_manager_;
00239   // Once our previous manager removes us, we can deallocate in any order
00240   this->factory_->lock.acquire();
00241   this->remove_from_dllist();
00242   result = prev->update_next_manager(this);
00243   this->factory_->lock.release();
00244   size_t block_number = 0;
00245   if (this->first_routing_slip_block_ != 0)
00246   {
00247     this->allocator_->free(this->first_routing_slip_block_->block_number());
00248     delete this->first_routing_slip_block_;
00249     this->first_routing_slip_block_ = 0;
00250   }
00251   if (this->first_event_block_ != 0)
00252   {
00253     this->allocator_->free(this->first_event_block_->block_number());
00254     delete this->first_event_block_;
00255     this->first_event_block_ = 0;
00256   }
00257   while (this->allocated_routing_slip_blocks_.pop(block_number) == 0)
00258   {
00259     this->allocator_->free(block_number);
00260   }
00261   while (this->allocated_event_blocks_.pop(block_number) == 0)
00262   {
00263     this->allocator_->free(block_number);
00264   }
00265   this->removed_ = true;
00266   Persistent_Storage_Block* callbackblock =
00267     this->allocator_->allocate_nowrite();
00268   callbackblock->set_callback(this->callback_);
00269   result &= this->allocator_->write(callbackblock);
00270   return result;
00271 }

void TAO_Notify::Routing_Slip_Persistence_Manager::remove_from_dllist  )  [private]
 

Remove ourselves from a linked list of Routing_Slip_Persistence_Managers.

Definition at line 789 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, next_manager_, and prev_manager_.

Referenced by release_all(), and remove().

00790 {
00791   // Since this is a private function, the caller should have done locking
00792   // on the factory before calling here.  The same is true for insertions.
00793   ACE_ASSERT(this->persisted());
00794   ACE_ASSERT(this->prev_manager_ != this);
00795   ACE_ASSERT(this->next_manager_ != this);
00796   this->prev_manager_->next_manager_ = this->next_manager_;
00797   this->next_manager_->prev_manager_ = this->prev_manager_;
00798   this->prev_manager_ = this;
00799   this->next_manager_ = this;
00800 }

void TAO_Notify::Routing_Slip_Persistence_Manager::set_callback Persistent_Callback callback  ) 
 

Set up callbacks.

Definition at line 43 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_GUARD, and ACE_SYNCH_MUTEX.

Referenced by TAO_Notify::Standard_Event_Persistence_Factory::create_routing_slip_persistence_manager(), and TAO_Notify::Routing_Slip::set_rspm().

00044 {
00045   ACE_GUARD(ACE_SYNCH_MUTEX, ace_mon, this->lock_);
00046   this->callback_ = callback;
00047 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::store const ACE_Message_Block event,
const ACE_Message_Block routing_slip
 

Store an event + routing slip.

Definition at line 202 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, and store_i().

Referenced by TAO_Notify::Routing_Slip::enter_state_saving().

00204 {
00205   bool result = false;
00206   ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result);
00207   if (!this->removed_)
00208   {
00209     result = store_i(event, routing_slip);
00210   }
00211   return result;
00212 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::store_event const ACE_Message_Block event  )  [private]
 

Definition at line 498 of file Routing_Slip_Persistence_Manager.cpp.

References TAO_Notify::Persistent_File_Allocator::allocate(), build_chain(), first_event_block_, TAO_Notify::Persistent_Storage_Block::set_allocator_owns(), ACE_Message_Block::total_length(), and TAO_Notify::Persistent_File_Allocator::write().

Referenced by store_i().

00500 {
00501   bool result = true;
00502   size_t event_size = event.total_length();
00503   if (event_size != 0)
00504   {
00505     if (this->first_event_block_ == 0)
00506     {
00507       this->first_event_block_ = this->allocator_->allocate();
00508       this->first_event_block_->set_allocator_owns(false);
00509     }
00510 
00511     result = this->build_chain(this->first_event_block_,
00512       this->event_header_, this->allocated_event_blocks_,
00513       event);
00514 
00515     result &= this->allocator_->write(this->first_event_block_);
00516   }
00517   return result;
00518 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::store_i const ACE_Message_Block event,
const ACE_Message_Block routing_slip
[private]
 

Definition at line 421 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ERROR, ACE_TEXT, TAO_Notify::Persistent_File_Allocator::allocate_nowrite(), TAO_Notify::Persistent_Storage_Block::block_number(), build_chain(), dllist_push_back(), TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::event_block, first_event_block_, LM_ERROR, TAO_Notify::Standard_Event_Persistence_Factory::lock, persisted(), TAO_Notify::Standard_Event_Persistence_Factory::preallocate_next_record(), routing_slip_header_, TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::serial_number, serial_number_, TAO_Notify::Persistent_Storage_Block::set_callback(), store_event(), TAO_Notify::Persistent_File_Allocator::write(), and write_first_routing_slip_block().

Referenced by store().

00423 {
00424   bool result = false;
00425 
00426   bool initially_persisted = this->persisted();
00427   if (!initially_persisted)
00428   {
00429     this->factory_->lock.acquire();
00430     this->factory_->preallocate_next_record(this->serial_number_,
00431       this->first_routing_slip_block_,
00432       this->routing_slip_header_.next_serial_number,
00433       this->routing_slip_header_.next_routing_slip_block);
00434     this->routing_slip_header_.serial_number = this->serial_number_;
00435   }
00436 
00437   result = this->build_chain(this->first_routing_slip_block_,
00438     this->routing_slip_header_, this->allocated_routing_slip_blocks_,
00439     routing_slip);
00440 
00441   if (result)
00442   {
00443     // No need for a callback here since we do our own below
00444     result &= this->store_event(event);
00445     // If we have an event block allocated, update our header
00446     if (this->first_event_block_ != 0)
00447     {
00448       this->routing_slip_header_.event_block =
00449         this->first_event_block_->block_number();
00450     }
00451     else
00452     {
00453       ACE_ERROR((LM_ERROR,
00454         ACE_TEXT(
00455           "(%P|%t) No Event is being stored with this routing slip.\n")
00456         ));
00457     }
00458     // Always write our first block out.
00459     this->dllist_push_back();
00460     result &= (this->write_first_routing_slip_block() != 0);
00461     // because the first rs blocks everywhere have been given sync, we are
00462     // guaranteed that they will be totally written by the time we get to this
00463     // empty callback-only block.
00464     Persistent_Storage_Block* callbackblock =
00465       this->allocator_->allocate_nowrite();
00466     callbackblock->set_callback(this->callback_);
00467     result &= this->allocator_->write(callbackblock);
00468   }
00469   if (!initially_persisted)
00470   {
00471     this->factory_->lock.release();
00472   }
00473   return result;
00474 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::store_root  ) 
 

Commit root data to disk, which should only be done for a root node.

Definition at line 50 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, build_chain(), TAO_Notify::Standard_Event_Persistence_Factory::get_preallocated_pointer(), TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::put_header(), routing_slip_header_, TAO_Notify::Routing_Slip_Persistence_Manager::Block_Header::serial_number, ACE_Message_Block::wr_ptr(), and TAO_Notify::Persistent_File_Allocator::write().

Referenced by TAO_Notify::Standard_Event_Persistence_Factory::open().

00051 {
00052   bool result = false;
00053 
00054   this->factory_->get_preallocated_pointer (
00055     this->routing_slip_header_.next_serial_number,
00056     this->routing_slip_header_.next_routing_slip_block);
00057 
00058   // we should already have a psb, but JIC
00059   ACE_ASSERT(this->first_routing_slip_block_ != 0);
00060   ACE_ASSERT(this->first_routing_slip_block_->block_number() ==
00061     ROUTING_SLIP_ROOT_BLOCK_NUMBER);
00062 
00063   // Don't take any chances.  Use hard-wired root serial number.
00064   this->routing_slip_header_.serial_number = ROUTING_SLIP_ROOT_SERIAL_NUMBER;
00065 
00066   // This will eventually break after something like 58000 years.
00067   // At such time we should change this to !=.
00068   ACE_ASSERT(this->routing_slip_header_.next_serial_number >
00069     ROUTING_SLIP_ROOT_SERIAL_NUMBER);
00070 
00071   ACE_Message_Block versioninfo(2);
00072   versioninfo.wr_ptr()[0] = 1; // Major version number
00073   versioninfo.wr_ptr()[1] = 0; // Minor version number
00074   versioninfo.wr_ptr(2);
00075   ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result);
00076   result = this->build_chain(this->first_routing_slip_block_,
00077     this->routing_slip_header_, this->allocated_routing_slip_blocks_,
00078     versioninfo);
00079   if (result)
00080   {
00081    this->routing_slip_header_.put_header(*this->first_routing_slip_block_);
00082    this->allocator_->write(this->first_routing_slip_block_);
00083   }
00084   return result;
00085 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::update const ACE_Message_Block routing_slip  ) 
 

Update the routing slip.

We must always overwrite the first block last, and it may not chance. Other blocks should be freed and reallocated.

Definition at line 215 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, persisted(), and update_i().

Referenced by TAO_Notify::Routing_Slip::enter_state_updating().

00216 {
00217   bool result = false;
00218   ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result);
00219   // If we have not gotten the event yet or we have no allocator, fail
00220   if (!this->removed_)
00221   {
00222     if (this->persisted())
00223     {
00224       result = update_i(routing_slip);
00225     }
00226   }
00227   return result;
00228 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::update_i const ACE_Message_Block routing_slip  )  [private]
 

Definition at line 477 of file Routing_Slip_Persistence_Manager.cpp.

References TAO_Notify::Persistent_File_Allocator::allocate_nowrite(), build_chain(), TAO_Notify::Persistent_Storage_Block::set_callback(), ACE_Message_Block::total_length(), and TAO_Notify::Persistent_File_Allocator::write().

Referenced by update().

00479 {
00480   bool result = true;
00481   size_t routing_slip_size = routing_slip.total_length();
00482   if (routing_slip_size != 0)
00483   {
00484     result = this->build_chain(this->first_routing_slip_block_,
00485       this->routing_slip_header_, this->allocated_routing_slip_blocks_,
00486       routing_slip);
00487 
00488     result &= this->allocator_->write(this->first_routing_slip_block_);
00489   }
00490   Persistent_Storage_Block* callbackblock =
00491     this->allocator_->allocate_nowrite();
00492   callbackblock->set_callback(this->callback_);
00493   result &= this->allocator_->write(callbackblock);
00494   return result;
00495 }

bool TAO_Notify::Routing_Slip_Persistence_Manager::update_next_manager Routing_Slip_Persistence_Manager next  )  [private]
 

Locked method to do the work of setting the next_manager_.

Definition at line 696 of file Routing_Slip_Persistence_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, next_manager_, TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::next_routing_slip_block, TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::next_serial_number, routing_slip_header_, and write_first_routing_slip_block().

Referenced by remove().

00698 {
00699   bool result = false;
00700   ACE_GUARD_RETURN(ACE_SYNCH_MUTEX, ace_mon, this->lock_, result);
00701   ACE_ASSERT(this->persisted());
00702   if (!this->removed_)
00703   {
00704     bool updated = false;
00705     if (this->next_manager_ != 0)
00706     {
00707       if (this->routing_slip_header_.next_serial_number !=
00708         next->routing_slip_header_.next_serial_number)
00709       {
00710         this->routing_slip_header_.next_serial_number =
00711           next->routing_slip_header_.next_serial_number;
00712         updated = true;
00713       }
00714       if (this->routing_slip_header_.next_routing_slip_block !=
00715         next->routing_slip_header_.next_routing_slip_block)
00716       {
00717         this->routing_slip_header_.next_routing_slip_block =
00718           next->routing_slip_header_.next_routing_slip_block;
00719         updated = true;
00720       }
00721     }
00722     if (updated)
00723     {
00724       this->write_first_routing_slip_block();
00725     }
00726   }
00727   return result;
00728 }

size_t TAO_Notify::Routing_Slip_Persistence_Manager::write_first_routing_slip_block bool  prepare_only = false  )  [private]
 

Write out our first event block.

Definition at line 756 of file Routing_Slip_Persistence_Manager.cpp.

References TAO_Notify::Routing_Slip_Persistence_Manager::Routing_Slip_Header::put_header(), routing_slip_header_, and TAO_Notify::Persistent_File_Allocator::write().

Referenced by store_i(), and update_next_manager().

00758 {
00759   size_t pos = this->routing_slip_header_.put_header(
00760     *this->first_routing_slip_block_);
00761   if (!prepare_only)
00762   {
00763     this->allocator_->write(this->first_routing_slip_block_);
00764   }
00765   return pos;
00766 }


Member Data Documentation

ACE_Unbounded_Stack<size_t> TAO_Notify::Routing_Slip_Persistence_Manager::allocated_event_blocks_ [private]
 

Definition at line 253 of file Routing_Slip_Persistence_Manager.h.

Referenced by remove().

ACE_Unbounded_Stack<size_t> TAO_Notify::Routing_Slip_Persistence_Manager::allocated_routing_slip_blocks_ [private]
 

Definition at line 254 of file Routing_Slip_Persistence_Manager.h.

Referenced by remove().

Persistent_File_Allocator* TAO_Notify::Routing_Slip_Persistence_Manager::allocator_ [private]
 

Definition at line 244 of file Routing_Slip_Persistence_Manager.h.

Persistent_Callback* TAO_Notify::Routing_Slip_Persistence_Manager::callback_ [private]
 

Definition at line 255 of file Routing_Slip_Persistence_Manager.h.

Event_Header TAO_Notify::Routing_Slip_Persistence_Manager::event_header_ [private]
 

Definition at line 246 of file Routing_Slip_Persistence_Manager.h.

ACE_Message_Block* TAO_Notify::Routing_Slip_Persistence_Manager::event_mb_ [private]
 

if these are non-zero we own 'em

Definition at line 258 of file Routing_Slip_Persistence_Manager.h.

Referenced by load(), reload(), and ~Routing_Slip_Persistence_Manager().

Standard_Event_Persistence_Factory* TAO_Notify::Routing_Slip_Persistence_Manager::factory_ [private]
 

Definition at line 245 of file Routing_Slip_Persistence_Manager.h.

Persistent_Storage_Block* TAO_Notify::Routing_Slip_Persistence_Manager::first_event_block_ [private]
 

Definition at line 248 of file Routing_Slip_Persistence_Manager.h.

Referenced by load(), remove(), store_event(), store_i(), and ~Routing_Slip_Persistence_Manager().

Persistent_Storage_Block* TAO_Notify::Routing_Slip_Persistence_Manager::first_routing_slip_block_ [private]
 

Definition at line 249 of file Routing_Slip_Persistence_Manager.h.

Referenced by load(), load_next(), persisted(), remove(), and ~Routing_Slip_Persistence_Manager().

ACE_SYNCH_MUTEX TAO_Notify::Routing_Slip_Persistence_Manager::lock_ [private]
 

Definition at line 241 of file Routing_Slip_Persistence_Manager.h.

Routing_Slip_Persistence_Manager* TAO_Notify::Routing_Slip_Persistence_Manager::next_manager_ [private]
 

Definition at line 252 of file Routing_Slip_Persistence_Manager.h.

Referenced by insert_before(), release_all(), remove_from_dllist(), Routing_Slip_Persistence_Manager(), and update_next_manager().

Routing_Slip_Persistence_Manager* TAO_Notify::Routing_Slip_Persistence_Manager::prev_manager_ [private]
 

We are part of a doubly-linked list.

Definition at line 251 of file Routing_Slip_Persistence_Manager.h.

Referenced by insert_before(), remove(), remove_from_dllist(), and Routing_Slip_Persistence_Manager().

bool TAO_Notify::Routing_Slip_Persistence_Manager::removed_ [private]
 

Definition at line 242 of file Routing_Slip_Persistence_Manager.h.

Routing_Slip_Header TAO_Notify::Routing_Slip_Persistence_Manager::routing_slip_header_ [private]
 

Definition at line 247 of file Routing_Slip_Persistence_Manager.h.

Referenced by load(), store_i(), store_root(), update_next_manager(), and write_first_routing_slip_block().

ACE_Message_Block* TAO_Notify::Routing_Slip_Persistence_Manager::routing_slip_mb_ [private]
 

Definition at line 259 of file Routing_Slip_Persistence_Manager.h.

Referenced by load(), reload(), and ~Routing_Slip_Persistence_Manager().

ACE_UINT64 TAO_Notify::Routing_Slip_Persistence_Manager::serial_number_ [private]
 

Definition at line 243 of file Routing_Slip_Persistence_Manager.h.

Referenced by is_root(), load(), load_next(), and store_i().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 13:34:24 2006 for TAO_CosNotification by doxygen 1.3.6