inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &abs_time)
{
   const boost::posix_time::ptime cur_time = microsec_clock::universal_time();
   //Windows uses relative wait times so check for negative waits
   //and implement as 0 wait to allow try-semantics as POSIX mandates.
   unsigned long time = 0u;
   if (abs_time == boost::posix_time::pos_infin){
      time = winapi::infinite_time;
   }
   else if(abs_time > cur_time){
      time = (abs_time - cur_time).total_milliseconds();
   }

   unsigned long ret = winapi::wait_for_single_object(handle, time);
   if(ret == winapi::wait_object_0){
      return true;
   }
   else if(ret == winapi::wait_timeout){
      return false;
   }
   else if(ret == winapi::wait_abandoned){ //Special case for orphaned mutexes
      winapi::release_mutex(handle);
      throw interprocess_exception(owner_dead_error);
   }
   else{
      error_info err = system_error_code();
      throw interprocess_exception(err);
   }
}
inline void create_tmp_and_clean_old(std::string &tmp_name)
{
   //First get the temp directory
   std::string root_tmp_name;
   get_tmp_base_dir(root_tmp_name);

   //If fails, check that it's because already exists
   if(!create_directory(root_tmp_name.c_str())){
      error_info info(system_error_code());
      if(info.get_error_code() != already_exists_error){
         throw interprocess_exception(info);
      }
   }

   #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
      tmp_folder(tmp_name);

      //If fails, check that it's because already exists
      if(!create_directory(tmp_name.c_str())){
         error_info info(system_error_code());
         if(info.get_error_code() != already_exists_error){
            throw interprocess_exception(info);
         }
      }
      //Now erase all old directories created in the previous boot sessions
      std::string subdir = tmp_name;
      subdir.erase(0, root_tmp_name.size()+1);
      delete_subdirectories(root_tmp_name, subdir.c_str());
   #else
      tmp_name = root_tmp_name;
   #endif
}
inline bool semaphore_open
   (sem_t *&handle, create_enum_t type, const char *origname,
    unsigned int count = 0, const permissions &perm = permissions())
{
   std::string name;
   #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
   add_leading_slash(origname, name);
   #else
   create_shared_dir_cleaning_old_and_get_filepath(origname, name);
   #endif

   //Create new mapping
   int oflag = 0;
   switch(type){
      case DoOpen:
      {
         //No addition
         handle = ::sem_open(name.c_str(), oflag);
      }
      break;
      case DoOpenOrCreate:
      case DoCreate:
      {
         while(1){
            oflag = (O_CREAT | O_EXCL);
            handle = ::sem_open(name.c_str(), oflag, perm.get_permissions(), count);
            if(handle != BOOST_INTERPROCESS_POSIX_SEM_FAILED){
               //We can't change semaphore permissions!
               //::fchmod(handle, perm.get_permissions());
               break;
            }
            else if(errno == EEXIST && type == DoOpenOrCreate){
               oflag = 0;
               if( (handle = ::sem_open(name.c_str(), oflag)) != BOOST_INTERPROCESS_POSIX_SEM_FAILED
                   || (errno != ENOENT) ){
                  break;
               }
            }
            else{
               break;
            }
         }
      }
      break;
      default:
      {
         error_info err(other_error);
         throw interprocess_exception(err);
      }
   }

   //Check for error
   if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
      throw interprocess_exception(error_info(errno));
   }

   return true;
}
Exemple #4
0
inline bool semaphore_open
   (sem_t *&handle, detail::create_enum_t type, const char *origname, mode_t mode,
    unsigned int count)
{
   std::string name;
   #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
   detail::add_leading_slash(origname, name);
   #else
   detail::create_tmp_dir_and_get_filename(origname, name);
   #endif

   //Create new mapping
   int oflag = 0;
   if(mode == read_only){
      oflag |= O_RDONLY;
   }
   else if(mode == read_write){
      oflag |= O_RDWR;
   }
   else{
      error_info err(mode_error);
      throw interprocess_exception(err);
   }

   switch(type){
      case detail::DoOpen:
         //No addition
      break;
      case detail::DoCreate:
         oflag |= (O_CREAT | O_EXCL);
      break;
      case detail::DoOpenOrCreate:
         oflag |= O_CREAT;
      break;
      default:
         {
            error_info err = other_error;
            throw interprocess_exception(err);
         }
   }

   //Open file using POSIX API
   if(oflag & O_CREAT)
      handle = sem_open(name.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU, count);
   else
      handle = sem_open(name.c_str(), oflag);

   //Check for error
   if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
      throw interprocess_exception(error_info(errno));
   }

   return true;
}
Exemple #5
0
   robust_mutex_lock_file()
   {
      permissions p;
      p.set_unrestricted();
      //Remove old lock files of other processes
      remove_old_robust_lock_files();
      //Create path and obtain lock file path for this process
      create_and_get_robust_lock_file_path(fname, get_current_process_id());

      //Now try to open or create the lock file
      fd = create_or_open_file(fname.c_str(), read_write, p);
      //If we can't open or create it, then something unrecoverable has happened
      if(fd == invalid_file()){
         throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: could not open or create file");
      }

      //Now we must take in care a race condition with another process
      //calling "remove_old_robust_lock_files()". No other threads from this
      //process will be creating the lock file because intermodule_singleton
      //guarantees this. So let's loop acquiring the lock and checking if we
      //can't exclusively create the file (if the file is erased by another process
      //then this exclusive open would fail). If the file can't be exclusively created
      //then we have correctly open/create and lock the file. If the file can
      //be exclusively created, then close previous locked file and try again.
      while(1){
         bool acquired;
         if(!try_acquire_file_lock(fd, acquired) || !acquired ){
            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: try_acquire_file_lock");
         }
         //Creating exclusively must fail with already_exists_error
         //to make sure we've locked the file and no one has
         //deleted it between creation and locking
         file_handle_t fd2 = create_new_file(fname.c_str(), read_write, p);
         if(fd2 != invalid_file()){
            close_file(fd);
            fd = fd2;
            continue;
         }
         //If exclusive creation fails with expected error go ahead
         else if(error_info(system_error_code()).get_error_code() == already_exists_error){ //must already exist
            //Leak descriptor to mantain the file locked until the process dies
            break;
         }
         //If exclusive creation fails with unexpected error throw an unrecoverable error
         else{
            close_file(fd);
            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error");
         }
      }
   }
inline void winapi_wrapper_wait_for_single_object(void *handle)
{
   unsigned long ret = winapi::wait_for_single_object(handle, winapi::infinite_time);
   if(ret != winapi::wait_object_0){
      if(ret != winapi::wait_abandoned){
         error_info err = system_error_code();
         throw interprocess_exception(err);
      }
      else{ //Special case for orphaned mutexes
         winapi::release_mutex(handle);
         throw interprocess_exception(owner_dead_error);
      }
   }
}
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
   #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
   //Posix does not support infinity absolute time so handle it here
   if(abs_time == boost::posix_time::pos_infin){
      semaphore_wait(handle);
      return true;
   }

   timespec tspec = ptime_to_timespec(abs_time);
   for (;;){
      int res = sem_timedwait(handle, &tspec);
      if(res == 0)
         return true;
      if (res > 0){
         //buggy glibc, copy the returned error code to errno
         errno = res;
      }
      if(system_error_code() == ETIMEDOUT){
         return false;
      }
      error_info err = system_error_code();
      throw interprocess_exception(err);
   }
   return false;
   #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS

   semaphore_wrapper_try_wrapper swtw(handle);
   ipcdetail::lock_to_wait<semaphore_wrapper_try_wrapper> lw(swtw);
   return ipcdetail::try_based_timed_lock(lw, abs_time);

   #endif   //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
   :  m_mut(), m_cond(), m_count(initialCount)
{
   if(m_count < 0){
      throw interprocess_exception(size_error);
   }
}
 void lock()
 {
    if(winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time) != winapi::wait_object_0){
       error_info err = system_error_code();
       throw interprocess_exception(err);
    }
 }
Exemple #10
0
inline void file_wrapper::truncate(offset_t length)
{
   if(!truncate_file(m_handle, length)){
      error_info err(system_error_code());
      throw interprocess_exception(err);
   }
}
Exemple #11
0
inline bool emulation_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
   typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
   if(abs_time == boost::posix_time::pos_infin){
      this->lock();
      return true;
   }
   const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
   handle_t old_id;
   ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
   if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
      if((unsigned int)(m_nLockCount+1) == 0){
         //Overflow, throw an exception
         throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
      } 
      ++m_nLockCount;
      return true;
   }
   if(m_mutex.timed_lock(abs_time)){
      ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
      m_nLockCount = 1;
      return true;
   }
   return false;
}
inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const geofeatures_boost::posix_time::ptime &abs_time)
{
   //Windows does not support infinity abs_time so check it
   if(abs_time == geofeatures_boost::posix_time::pos_infin){
      winapi_wrapper_wait_for_single_object(handle);
      return true;
   }
   const geofeatures_boost::posix_time::ptime cur_time = microsec_clock::universal_time();
   //Windows uses relative wait times so check for negative waits
   //and implement as 0 wait to allow try-semantics as POSIX mandates.
   unsigned long ret = winapi::wait_for_single_object
      ( handle
      , (abs_time <= cur_time) ? 0u
                                 : (abs_time - cur_time).total_milliseconds()
      );
   if(ret == winapi::wait_object_0){
      return true;
   }
   else if(ret == winapi::wait_timeout){
      return false;
   }
   else{
      error_info err = system_error_code();
      throw interprocess_exception(err);
   }
}
Exemple #13
0
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
   #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
   timespec tspec = detail::ptime_to_timespec(abs_time);
   for (;;){
      int res = sem_timedwait(handle, &tspec);
      if(res == 0)
         return true;
      if (res > 0){
         //buggy glibc, copy the returned error code to errno
         errno = res;
      }
      if(system_error_code() == ETIMEDOUT){
         return false;
      }
      throw interprocess_exception(system_error_code());
   }
   return false;
   #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
   boost::posix_time::ptime now;
   while((now = microsec_clock::universal_time()) < abs_time){
      if(semaphore_try_wait(handle))
         return true;
      thread_yield();
   }
   return false;
   #endif   //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
Exemple #14
0
inline void semaphore_wait(sem_t *handle)
{
   int ret = sem_wait(handle);
   if(ret != 0){
      throw interprocess_exception(system_error_code());
   }
}
Exemple #15
0
inline void semaphore_post(sem_t *handle)
{
   int ret = sem_post(handle);
   if(ret != 0){
      error_info err = system_error_code();
      throw interprocess_exception(err);
   }
}
Exemple #16
0
 //!Constructor. Takes barrier attributes to initialize the barrier
 barrier_initializer(pthread_barrier_t &mut,
                     pthread_barrierattr_t &mut_attr,
                     int count)
 : mp_barrier(&mut)
 {
    if(pthread_barrier_init(mp_barrier, &mut_attr, count) != 0)
       throw interprocess_exception("pthread_barrier_init failed");
 }
 //!Creates heap memory and initializes the segment manager.
 //!This can throw.
 basic_managed_heap_memory(std::size_t size)
    :  m_heapmem(size, char(0))
 {
    if(!base_t::create_impl(&m_heapmem[0], size)){
       this->priv_close();
       throw interprocess_exception();
    }
 }
Exemple #18
0
 //!Constructor
 mutexattr_wrapper(bool recursive = false)
 {
    if(pthread_mutexattr_init(&m_attr)!=0 ||
       pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED)!= 0 ||
        (recursive &&
         pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE)!= 0 ))
       throw interprocess_exception("pthread_mutexattr_xxxx failed");
 }
inline bool barrier::wait()
{
    int res = pthread_barrier_wait(&m_barrier);

    if (res != PTHREAD_BARRIER_SERIAL_THREAD && res != 0) {
        throw interprocess_exception(res);
    }
    return res == PTHREAD_BARRIER_SERIAL_THREAD;
}
 //!Creates and places the segment manager. This can throw
 basic_managed_external_buffer
 (open_only_t, void *addr, std::size_t size)
 {
     //Check if alignment is correct
     assert((0 == (((std::size_t)addr) & (AllocationAlgorithm::Alignment - std::size_t(1u)))));
     if(!base_t::open_impl(addr, size)) {
         throw interprocess_exception();
     }
 }
Exemple #21
0
inline bool semaphore_open
   (sem_t *&handle, ipcdetail::create_enum_t type, const char *origname, 
    unsigned int count, const permissions &perm = permissions())
{
   std::string name;
   #ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
   ipcdetail::add_leading_slash(origname, name);
   #else
   ipcdetail::create_tmp_and_clean_old_and_get_filename(origname, name);
   #endif

   //Create new mapping
   int oflag = 0;
   switch(type){
      case ipcdetail::DoOpen:
         //No addition
      break;
      case ipcdetail::DoCreate:
         oflag |= (O_CREAT | O_EXCL);
      break;
      case ipcdetail::DoOpenOrCreate:
         oflag |= O_CREAT;
      break;
      default:
         {
            error_info err = other_error;
            throw interprocess_exception(err);
         }
   }

   //Open file using POSIX API
   if(oflag & O_CREAT)
      handle = sem_open(name.c_str(), oflag, perm.get_permissions(), count);
   else
      handle = sem_open(name.c_str(), oflag);

   //Check for error
   if(handle == BOOST_INTERPROCESS_POSIX_SEM_FAILED){
      throw interprocess_exception(error_info(errno));
   }

   return true;
}
inline interprocess_condition::interprocess_condition()
{
   int res;
   pthread_condattr_t cond_attr;
   res = pthread_condattr_init(&cond_attr);
   if(res != 0){
      throw interprocess_exception("pthread_condattr_init failed");
   }
   res = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
   if(res != 0){
      pthread_condattr_destroy(&cond_attr);
      throw interprocess_exception(res);
   }
   res = pthread_cond_init(&m_condition, &cond_attr);
   pthread_condattr_destroy(&cond_attr);
   if(res != 0){
      throw interprocess_exception(res);
   }
}
Exemple #23
0
inline void semaphore_init(sem_t *handle, int initialCount)
{
   int ret = sem_init(handle, 1, initialCount);
   //According to SUSV3 version 2003 edition, the return value of a successful
   //sem_init call is not defined, but -1 is returned on failure.
   //In the future, a successful call might be required to return 0.
   if(ret == -1){
      throw interprocess_exception(system_error_code());
   }
}
Exemple #24
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 #25
0
inline bool semaphore_try_wait(sem_t *handle)
{
   int res = sem_trywait(handle);
   if(res == 0)
      return true;
   if(system_error_code() == EAGAIN){
      return false;
   }
   throw interprocess_exception(system_error_code());
   return false;
}
Exemple #26
0
inline void windows_semaphore::wait(void)
{
   sync_handles &handles =
      intermodule_singleton<sync_handles>::get();
   //This can throw
   void *hnd = handles.obtain_semaphore(this->id_, 0);
   unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
   if(ret == winapi::wait_failed){
      error_info err(winapi::get_last_error());
      throw interprocess_exception(err);
   }
}
inline void interprocess_recursive_mutex::lock()
{
   #ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
      boost::posix_time::ptime wait_time
         = boost::posix_time::microsec_clock::universal_time()
         + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
      if (!mutex.timed_lock(wait_time)){
         throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
      }
   #else
      mutex.lock();
   #endif
}
inline void tmp_filename(const char *filename, std::string &tmp_name)
{
   const char *tmp_dir = get_temporary_path();
   if(!tmp_dir){
      error_info err = system_error_code();
      throw interprocess_exception(err);
   }
   tmp_name = tmp_dir;

   //Remove final null.
   tmp_name += "/boost_interprocess/";
   tmp_name += filename;
}
Exemple #29
0
inline bool file_wrapper::priv_open_or_create
   (detail::create_enum_t type, 
    const char *filename,
    mode_t mode)
{
   m_filename = filename;

   if(mode != read_only && mode != read_write){
      error_info err(mode_error);
      throw interprocess_exception(err);
   }

   //Open file existing native API to obtain the handle
   switch(type){
      case detail::DoOpen:
         m_handle = open_existing_file(filename, mode);
      break;
      case detail::DoCreate:
         m_handle = create_new_file(filename, mode);
      break;
      case detail::DoOpenOrCreate:
         m_handle = create_or_open_file(filename, mode);
      break;
      default:
         {
            error_info err = other_error;
            throw interprocess_exception(err);
         }
   }

   //Check for error
   if(m_handle == invalid_file()){
      throw interprocess_exception(error_info(system_error_code()));
   }

   m_mode = mode;
   return true;
}
 bool try_lock()
 {
    unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, 0);
    if(ret == winapi::wait_object_0){
       return true;
    }
    else if(ret == winapi::wait_timeout){
       return false;
    }
    else{
       error_info err = system_error_code();
       throw interprocess_exception(err);
    }
 }