Exemple #1
0
inline void robust_spin_mutex<Mutex>::consistent()
{
   //This function supposes the previous state was "fixing"
   //and the current process holds the mutex
   if(atomic_read32(&this->state) != fixing_state &&
      atomic_read32(&this->owner) != (boost::uint32_t)get_current_process_id()){
      throw interprocess_exception(lock_error, "Broken id");
   }
   //If that's the case, just update mutex state
   atomic_write32(&this->state, correct_state);
}
Exemple #2
0
inline void robust_spin_mutex<Mutex>::unlock()
{
   //If in "fixing" state, unlock and mark the mutex as unrecoverable
   //so next locks will fail and all threads will be notified that the
   //data protected by the mutex was not recoverable.
   if(atomic_read32(&this->state) == fixing_state){
      atomic_write32(&this->state, broken_state);
   }
   //Write an invalid owner to minimize pid reuse possibility
   atomic_write32(&this->owner, get_invalid_process_id());
   mtx.unlock();
}
Exemple #3
0
inline bool robust_spin_mutex<Mutex>::check_if_owner_dead_and_take_ownership_atomically()
{
   boost::uint32_t cur_owner = get_current_process_id();
   boost::uint32_t old_owner = atomic_read32(&this->owner), old_owner2;
   //The cas loop guarantees that only one thread from this or another process
   //will succeed taking ownership
   do{
      //Check if owner is dead
      if(!this->is_owner_dead(old_owner)){
         return false;
      }
      //If it's dead, try to mark this process as the owner in the owner field
      old_owner2 = old_owner;
      old_owner = atomic_cas32(&this->owner, cur_owner, old_owner);
   }while(old_owner2 != old_owner);
   //If success, we fix mutex internals to assure our ownership
   mutex_traits_t::take_ownership(mtx);
   return true;
}
inline void robust_spin_mutex<Mutex>::lock()
{
   //If the mutex is broken (recovery didn't call consistent()),
   //then throw an exception
   if(atomic_read32(&this->state) == broken_state){
      throw interprocess_exception(lock_error, "Broken id");
   }

   //This function provokes intermodule_singleton instantiation
   if(!this->lock_own_unique_file()){
      throw interprocess_exception(lock_error, "Broken id");
   }

   //Now the logic. Try to lock, if successful mark the owner
   //if it fails, start recovery logic
   unsigned int spin_count = 0;
   while(1){
      if (mtx.try_lock()){
         atomic_write32(&this->owner, get_current_process_id());
         break;
      }
      else{
         //Do the dead owner checking each spin_threshold lock tries
         ipcdetail::thread_yield();
         ++spin_count;
         if(spin_count > spin_threshold){
            //Check if owner dead and take ownership if possible
            if(!this->robust_check()){
               spin_count = 0;
            }
            else{
               break;
            }
         }
      }
   }
}
Exemple #5
0
inline bool robust_spin_mutex<Mutex>::try_lock()
{
   //Same as lock() but without spinning
   if(atomic_read32(&this->state) == broken_state){
      throw interprocess_exception(lock_error, "Broken id");
   }

   if(!this->lock_own_unique_file()){
      throw interprocess_exception(lock_error, "Broken id");
   }

   if (mtx.try_lock()){
      atomic_write32(&this->owner, get_current_process_id());
      return true;
   }
   else{
      if(!this->robust_check()){
         return false;
      }
      else{
         return true;
      }
   }
}
Exemple #6
0
inline bool robust_spin_mutex<Mutex>::previous_owner_dead()
{
   //Notifies if a owner recovery has been performed in the last lock()
   return atomic_read32(&this->state) == fixing_state;
}
Exemple #7
0
 DWORD atomicGetValue32(DWORD &value)
 {
   return atomic_read32((boost::uint32_t *)&value);
 }