#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 307 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().
00308 { 00309 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_, 0); 00310 block_number = this->free_blocks_.find_first_bit(false); 00311 return true; 00312 } |
|
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 323 of file Persistent_File_Allocator.cpp. References pstore_, and TAO_Notify::Random_File::size().
00324 { 00325 return this->pstore_.size (); 00326 } |
|
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 299 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().
00300 { 00301 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->free_blocks_lock_); 00302 ACE_ASSERT (this->free_blocks_.is_set (block_number)); 00303 this->free_blocks_.set_bit(block_number, false); 00304 } |
|
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 && (psbtemp != 0)) 00253 { 00254 cached = ((*psbtemp)->block_number() == psb->block_number()); 00255 } 00256 } 00257 // this needs to be done in the guarded section 00258 if (cached && (0 != psbtemp)) 00259 { 00260 ACE_OS::memcpy(psb->data(), (*psbtemp)->data(), this->block_size()); 00261 } 00262 } 00263 if (!cached) 00264 { 00265 result = pstore_.read(psb->block_number(), psb->data()); 00266 } 00267 } 00268 return result; 00269 } |
|
The worker's execution thread.
Definition at line 345 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().
00346 { 00347 // We need this because we could be working on writing data 00348 // when a call to terminate comes in! 00349 bool do_more_work = true; 00350 while (do_more_work) 00351 { 00352 do_more_work = false; 00353 Persistent_Storage_Block * blk = 0; 00354 { 00355 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00356 while (this->block_queue_.is_empty() && !terminate_thread_) 00357 { 00358 this->wake_up_thread_.wait(); 00359 } 00360 // Awkward interface to peek at head of unbounded queue 00361 Persistent_Storage_Block ** pblk = 0; 00362 if (0 == this->block_queue_.get(pblk)) 00363 { 00364 do_more_work = true; 00365 blk = *pblk; 00366 } 00367 } 00368 if (0 != blk) 00369 { 00370 Persistent_Callback *callback = blk->get_callback(); 00371 if (!blk->get_no_write()) 00372 { 00373 pstore_.write(blk->block_number(), blk->data(), blk->get_sync()); 00374 } 00375 { 00376 Persistent_Storage_Block * blk2 = 0; 00377 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00378 this->block_queue_.dequeue_head (blk2); 00379 // if this triggers, someone pushed onto the head of the queue 00380 // or removed the head from the queue without telling ME. 00381 ACE_ASSERT (blk2 == blk); 00382 } 00383 // If we own the block, then delete it. 00384 if (blk->get_allocator_owns()) 00385 { 00386 delete blk; 00387 blk = 0; 00388 } 00389 if (0 != callback) 00390 { 00391 callback->persist_complete(); 00392 } 00393 } 00394 } 00395 this->terminate_thread_ = false; 00396 this->thread_active_ = false; 00397 } |
|
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 329 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().
00330 { 00331 if (this->thread_active_) 00332 { 00333 { 00334 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->queue_lock_); 00335 this->terminate_thread_ = true; 00336 this->wake_up_thread_.signal(); 00337 } 00338 this->thread_manager_.close(); 00339 ACE_ASSERT (!this->terminate_thread_); 00340 ACE_ASSERT (!this->thread_active_); 00341 } 00342 } |
|
Used during thread startup to cast us back to ourselves and call the run() method. Definition at line 315 of file Persistent_File_Allocator.cpp. References run().
00316 { 00317 Persistent_File_Allocator* pfa = static_cast<Persistent_File_Allocator*> (arg); 00318 pfa->run(); 00319 return 0; 00320 } |
|
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(). |