#include <Persistent_File_Allocator.h>
Collaboration diagram for TAO_Notify::Persistent_File_Allocator:
Public Member Functions | |
Persistent_File_Allocator () | |
The constructor. | |
~Persistent_File_Allocator () | |
The destructor. | |
bool | open (const ACE_TCHAR *filename, const size_t block_size=512) |
void | shutdown () |
Wait for pending I/O and terminate our work thread. | |
Persistent_Storage_Block * | allocate () |
Persistent_Storage_Block * | allocate_at (size_t block_number) |
Allocate a new Persistent_Storage_Block at a given address. | |
Persistent_Storage_Block * | allocate_nowrite () |
Allocate a PSB that is marked to not persist. | |
void | used (size_t block_number) |
Mark a block as used, removing it from the free list. | |
void | free (size_t block_number) |
Mark a block number as able to be used again. | |
size_t | block_size () const |
Access block size. | |
bool | read (Persistent_Storage_Block *psb) |
Read data into a PSB. | |
bool | write (Persistent_Storage_Block *psb) |
Write this block to the file,. | |
size_t | file_size () const |
for information (unit test) only. | |
Private Member Functions | |
void | free_block (const size_t block_number) |
Free a previously assigned block. | |
bool | allocate_block (size_t &block_number) |
Find and allocate a free block. | |
void | shutdown_thread () |
Wait for pending I/O to complete and shut our worker thread down safely. | |
void | run () |
The worker's execution thread. | |
Static Private Member Functions | |
ACE_THR_FUNC_RETURN | thr_func (void *arg) |
Private Attributes | |
ACE_Thread_Manager | thread_manager_ |
Random_File | pstore_ |
Bit_Vector | free_blocks_ |
ACE_Unbounded_Queue< Persistent_Storage_Block * > | block_queue_ |
ACE_SYNCH_MUTEX | lock_ |
ACE_SYNCH_MUTEX | free_blocks_lock_ |
ACE_SYNCH_MUTEX | queue_lock_ |
bool | terminate_thread_ |
bool | thread_active_ |
ACE_SYNCH_CONDITION | wake_up_thread_ |
Maintains a free list, write queue, allocations of new blocks, reads, and writes. This class also manages a thread that performs background updating of a Random_File. @todo this is too much for one class to do. It should be refactored. @todo: we shouldn't arbitrarily use a thread.
Definition at line 127 of file Persistent_File_Allocator.h.
|
The constructor.
Definition at line 127 of file Persistent_File_Allocator.cpp.
00128 : pstore_() 00129 , terminate_thread_(false) 00130 , thread_active_(false) 00131 , wake_up_thread_(queue_lock_) 00132 { 00133 } |
|
The destructor.
Definition at line 135 of file Persistent_File_Allocator.cpp. References shutdown_thread().
00136 { 00137 this->shutdown_thread(); 00138 } |
|
Allocate a new Persistent_Storage_Block and initialize it to an unused block of storage. Definition at line 160 of file Persistent_File_Allocator.cpp. References ACE_DEBUG, ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, ACE_TEXT(), allocate_at(), allocate_block(), DEBUG_LEVEL, and LM_DEBUG. Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::build_chain(), TAO_Notify::Standard_Event_Persistence_Factory::get_preallocated_pointer(), and TAO_Notify::Routing_Slip_Persistence_Manager::store_event().
00161 { 00162 Persistent_Storage_Block* result = 0; 00163 size_t block_number = 0; 00164 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); 00165 if (!this->allocate_block(block_number)) 00166 { 00167 //@@todo: this should never happen 00168 // why not. What if the disk is full? Oh, I see we 00169 // allocate non-existent blocks. FIX this 00170 } 00171 if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, 00172 ACE_TEXT ("(%P|%t) Persistent_File_Allocator::allocate: %d\n"), 00173 static_cast<int> (block_number) 00174 )); 00175 result = this->allocate_at(block_number); 00176 return result; 00177 } |
|
Allocate a new Persistent_Storage_Block at a given address.
Definition at line 180 of file Persistent_File_Allocator.cpp. References ACE_DEBUG, ACE_NEW_RETURN, ACE_TEXT(), DEBUG_LEVEL, LM_DEBUG, and used(). Referenced by allocate(), TAO_Notify::Routing_Slip_Persistence_Manager::load(), and TAO_Notify::Routing_Slip_Persistence_Manager::reload_chain().
00181 { 00182 Persistent_Storage_Block* result = 0; 00183 this->used(block_number); 00184 if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, 00185 ACE_TEXT ("(%P|%t) Persistent_File_Allocator::allocate at : %d\n"), 00186 static_cast<int> (block_number) 00187 )); 00188 ACE_NEW_RETURN(result, Persistent_Storage_Block( 00189 block_number, 00190 this->block_size()), 00191 0); 00192 return result; 00193 } |
|
Find and allocate a free block.
Definition at line 306 of file Persistent_File_Allocator.cpp. References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, TAO_Notify::Bit_Vector::find_first_bit(), and free_blocks_. Referenced by allocate().
00307 { 00308 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_, 0); 00309 block_number = this->free_blocks_.find_first_bit(false); 00310 return true; 00311 } |
|
Allocate a PSB that is marked to not persist.
Definition at line 196 of file Persistent_File_Allocator.cpp. References ACE_NEW_RETURN, and TAO_Notify::Persistent_Storage_Block::set_no_write(). Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::remove(), TAO_Notify::Routing_Slip_Persistence_Manager::store_i(), and TAO_Notify::Routing_Slip_Persistence_Manager::update_i().
00197 { 00198 Persistent_Storage_Block* result = 0; 00199 ACE_NEW_RETURN (result, 00200 Persistent_Storage_Block (static_cast<size_t> (~0), 0), 00201 0); 00202 result->set_no_write(); 00203 00204 return result; 00205 } |
|
Access block size.
Definition at line 231 of file Persistent_File_Allocator.cpp. References TAO_Notify::Random_File::block_size(), and pstore_. Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::fill_block(), TAO_Notify::Routing_Slip_Persistence_Manager::load(), read(), and TAO_Notify::Routing_Slip_Persistence_Manager::reload_chain().
00232 { 00233 return pstore_.block_size(); 00234 } |
|
for information (unit test) only.
Definition at line 322 of file Persistent_File_Allocator.cpp. References pstore_, and TAO_Notify::Random_File::size().
00323 { 00324 return this->pstore_.size (); 00325 } |
|
Mark a block number as able to be used again.
Definition at line 220 of file Persistent_File_Allocator.cpp. References ACE_ASSERT, ACE_DEBUG, ACE_TEXT(), DEBUG_LEVEL, free_block(), and LM_DEBUG. Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::build_chain(), and TAO_Notify::Routing_Slip_Persistence_Manager::remove().
00221 { 00222 if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, 00223 ACE_TEXT ("(%P|%t) Persistent_File_Allocator::free: %d\n"), 00224 static_cast<int> (block_number) 00225 )); 00226 ACE_ASSERT (this->free_blocks_.is_set (block_number)); 00227 this->free_block(block_number); 00228 } |
|
Free a previously assigned block.
Definition at line 298 of file Persistent_File_Allocator.cpp. References ACE_ASSERT, ACE_GUARD, ACE_SYNCH_MUTEX, free_blocks_, and TAO_Notify::Bit_Vector::set_bit(). Referenced by free().
00299 { 00300 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_); 00301 ACE_ASSERT (this->free_blocks_.is_set (block_number)); 00302 this->free_blocks_.set_bit(block_number, false); 00303 } |
|
Definition at line 141 of file Persistent_File_Allocator.cpp. References TAO_Notify::Random_File::open(), pstore_, ACE_Thread_Manager::spawn(), and thread_active_. Referenced by TAO_Notify::Standard_Event_Persistence_Factory::open().
00143 { 00144 bool file_opened = this->pstore_.open(filename, block_size); 00145 if (file_opened) 00146 { 00147 this->thread_active_ = true; 00148 this->thread_manager_.spawn(this->thr_func, this); 00149 } 00150 return file_opened; 00151 } |
|
Read data into a PSB. Data will come either from the queue of blocks to be written, or it will be read from the file if there are no queued write requests for this block. Definition at line 237 of file Persistent_File_Allocator.cpp. References ACE_GUARD_RETURN, ACE_SYNCH_MUTEX, TAO_Notify::Persistent_Storage_Block::block_number(), block_queue_, block_size(), TAO_Notify::Persistent_Storage_Block::data(), ACE_Unbounded_Queue< Persistent_Storage_Block * >::get(), ACE_OS::memcpy(), pstore_, TAO_Notify::Random_File::read(), ACE_Unbounded_Queue< Persistent_Storage_Block * >::size(), and thread_active_. Referenced by TAO_Notify::Routing_Slip_Persistence_Manager::reload_chain().
00238 { 00239 bool result = this->thread_active_; 00240 bool cached = false; 00241 if (result) 00242 { 00243 Persistent_Storage_Block** psbtemp = 0; 00244 { 00245 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_, false); 00246 size_t queue_size = this->block_queue_.size(); 00247 for (size_t idx = 0; !cached && (idx < queue_size); ++idx) 00248 { 00249 // We want to start at the end of the queue and work backwards... 00250 size_t actual_block = (queue_size - idx) - 1; 00251 if (0 == this->block_queue_.get(psbtemp, actual_block)) 00252 { 00253 cached = ((*psbtemp)->block_number() == psb->block_number()); 00254 } 00255 } 00256 // this needs to be done in the guarded section 00257 if (cached && (0 != psbtemp)) 00258 { 00259 ACE_OS::memcpy(psb->data(), (*psbtemp)->data(), this->block_size()); 00260 } 00261 } 00262 if (!cached) 00263 { 00264 result = pstore_.read(psb->block_number(), psb->data()); 00265 } 00266 } 00267 return result; 00268 } |
|
The worker's execution thread.
Definition at line 344 of file Persistent_File_Allocator.cpp. References ACE_ASSERT, ACE_GUARD, ACE_SYNCH_MUTEX, TAO_Notify::Persistent_Storage_Block::block_number(), block_queue_, TAO_Notify::Persistent_Storage_Block::data(), ACE_Unbounded_Queue< Persistent_Storage_Block * >::dequeue_head(), ACE_Unbounded_Queue< Persistent_Storage_Block * >::get(), TAO_Notify::Persistent_Storage_Block::get_allocator_owns(), TAO_Notify::Persistent_Storage_Block::get_callback(), TAO_Notify::Persistent_Storage_Block::get_no_write(), TAO_Notify::Persistent_Storage_Block::get_sync(), ACE_Unbounded_Queue< Persistent_Storage_Block * >::is_empty(), TAO_Notify::Persistent_Callback::persist_complete(), pstore_, terminate_thread_, thread_active_, wake_up_thread_, and TAO_Notify::Random_File::write(). Referenced by thr_func().
00345 { 00346 // We need this because we could be working on writing data 00347 // when a call to terminate comes in! 00348 bool do_more_work = true; 00349 while (do_more_work) 00350 { 00351 do_more_work = false; 00352 Persistent_Storage_Block * blk = 0; 00353 { 00354 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00355 while (this->block_queue_.is_empty() && !terminate_thread_) 00356 { 00357 this->wake_up_thread_.wait(); 00358 } 00359 // Awkward interface to peek at head of unbounded queue 00360 Persistent_Storage_Block ** pblk = 0; 00361 if (0 == this->block_queue_.get(pblk)) 00362 { 00363 do_more_work = true; 00364 blk = *pblk; 00365 } 00366 } 00367 if (0 != blk) 00368 { 00369 Persistent_Callback *callback = blk->get_callback(); 00370 if (!blk->get_no_write()) 00371 { 00372 pstore_.write(blk->block_number(), blk->data(), blk->get_sync()); 00373 } 00374 { 00375 Persistent_Storage_Block * blk2 = 0; 00376 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00377 this->block_queue_.dequeue_head (blk2); 00378 // if this triggers, someone pushed onto the head of the queue 00379 // or removed the head from the queue without telling ME. 00380 ACE_ASSERT (blk2 == blk); 00381 } 00382 // If we own the block, then delete it. 00383 if (blk->get_allocator_owns()) 00384 { 00385 delete blk; 00386 blk = 0; 00387 } 00388 if (0 != callback) 00389 { 00390 callback->persist_complete(); 00391 } 00392 } 00393 } 00394 this->terminate_thread_ = false; 00395 this->thread_active_ = false; 00396 } |
|
Wait for pending I/O and terminate our work thread.
Definition at line 154 of file Persistent_File_Allocator.cpp. References shutdown_thread(). Referenced by TAO_Notify::Standard_Event_Persistence_Factory::~Standard_Event_Persistence_Factory().
00155 { 00156 this->shutdown_thread(); 00157 } |
|
Wait for pending I/O to complete and shut our worker thread down safely.
Definition at line 328 of file Persistent_File_Allocator.cpp. References ACE_ASSERT, ACE_GUARD, ACE_SYNCH_MUTEX, ACE_Thread_Manager::close(), terminate_thread_, thread_active_, and wake_up_thread_. Referenced by shutdown(), and ~Persistent_File_Allocator().
00329 { 00330 if (this->thread_active_) 00331 { 00332 { 00333 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00334 this->terminate_thread_ = true; 00335 this->wake_up_thread_.signal(); 00336 } 00337 this->thread_manager_.close(); 00338 ACE_ASSERT (!this->terminate_thread_); 00339 ACE_ASSERT (!this->thread_active_); 00340 } 00341 } |
|
Used during thread startup to cast us back to ourselves and call the run() method. Definition at line 314 of file Persistent_File_Allocator.cpp. References run().
00315 { 00316 Persistent_File_Allocator* pfa = static_cast<Persistent_File_Allocator*> (arg); 00317 pfa->run(); 00318 return 0; 00319 } |
|
Mark a block as used, removing it from the free list.
Definition at line 208 of file Persistent_File_Allocator.cpp. References ACE_ASSERT, ACE_DEBUG, ACE_GUARD, ACE_SYNCH_MUTEX, ACE_TEXT(), DEBUG_LEVEL, free_blocks_, LM_DEBUG, and TAO_Notify::Bit_Vector::set_bit(). Referenced by allocate_at().
00209 { 00210 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_); 00211 if (DEBUG_LEVEL > 0) ACE_DEBUG ((LM_DEBUG, 00212 ACE_TEXT ("(%P|%t) Persistent_File_Allocator::used: %d\n"), 00213 static_cast<int> (block_number) 00214 )); 00215 ACE_ASSERT (!this->free_blocks_.is_set (block_number)); 00216 this->free_blocks_.set_bit(block_number, true); 00217 } |
|
|
Definition at line 194 of file Persistent_File_Allocator.h. |
|
Definition at line 193 of file Persistent_File_Allocator.h. Referenced by allocate_block(), free_block(), and used(). |
|
Definition at line 196 of file Persistent_File_Allocator.h. |
|
Definition at line 195 of file Persistent_File_Allocator.h. |
|
Definition at line 192 of file Persistent_File_Allocator.h. Referenced by block_size(), file_size(), open(), read(), and run(). |
|
Definition at line 197 of file Persistent_File_Allocator.h. |
|
Definition at line 198 of file Persistent_File_Allocator.h. Referenced by run(), and shutdown_thread(). |
|
Definition at line 199 of file Persistent_File_Allocator.h. Referenced by open(), read(), run(), shutdown_thread(), and write(). |
|
Definition at line 191 of file Persistent_File_Allocator.h. |
|
Definition at line 200 of file Persistent_File_Allocator.h. Referenced by run(), shutdown_thread(), and write(). |