Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:32

0001  //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
0012 #define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 
0025 #include <boost/interprocess/sync/cv_status.hpp>
0026 #include <boost/interprocess/creation_tags.hpp>
0027 #include <boost/interprocess/permissions.hpp>
0028 #include <boost/interprocess/detail/interprocess_tester.hpp>
0029 #include <boost/interprocess/sync/windows/named_sync.hpp>
0030 #include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
0031 #include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
0032 
0033 namespace boost {
0034 namespace interprocess {
0035 namespace ipcdetail {
0036 
0037 template<class CharT>
0038 struct named_cond_callbacks_str;
0039 
0040 template<>
0041 struct named_cond_callbacks_str<char>
0042 {
0043    static const char* ipc_cond()
0044    {  return "Global\\bipc.cond.";  }
0045 
0046    static const char* bq()
0047    {  return "_bq";  }
0048 
0049    static const char* bl()
0050    {  return "_bl";  }
0051 
0052    static const char* ul()
0053    {  return "_ul";  }
0054 };
0055 
0056 template<>
0057 struct named_cond_callbacks_str<wchar_t>
0058 {
0059    static const wchar_t* ipc_cond()
0060    {  return L"Global\\bipc.cond.";  }
0061 
0062    static const wchar_t* bq()
0063    {  return L"_bq";  }
0064 
0065    static const wchar_t* bl()
0066    {  return L"_bl";  }
0067 
0068    static const wchar_t* ul()
0069    {  return L"_ul";  }
0070 };
0071 
0072 class winapi_named_condition_any
0073 {
0074    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0075 
0076    //Non-copyable
0077    winapi_named_condition_any();
0078    winapi_named_condition_any(const winapi_named_condition_any &);
0079    winapi_named_condition_any &operator=(const winapi_named_condition_any &);
0080    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0081 
0082    public:
0083    winapi_named_condition_any
0084       (create_only_t, const char *name, const permissions &perm = permissions())
0085       : m_condition_data()
0086    {
0087       named_cond_callbacks callbacks(m_condition_data.get_members());
0088       m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
0089    }
0090 
0091    winapi_named_condition_any
0092       (open_or_create_t, const char *name, const permissions &perm = permissions())
0093       : m_condition_data()
0094    {
0095       named_cond_callbacks callbacks(m_condition_data.get_members());
0096       m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
0097    }
0098 
0099    winapi_named_condition_any(open_only_t, const char *name)
0100       : m_condition_data()
0101    {
0102       named_cond_callbacks callbacks(m_condition_data.get_members());
0103       m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
0104    }
0105 
0106    #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0107 
0108    winapi_named_condition_any
0109       (create_only_t, const wchar_t *name, const permissions &perm = permissions())
0110       : m_condition_data()
0111    {
0112       named_cond_callbacks callbacks(m_condition_data.get_members());
0113       m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
0114    }
0115 
0116    winapi_named_condition_any
0117       (open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
0118       : m_condition_data()
0119    {
0120       named_cond_callbacks callbacks(m_condition_data.get_members());
0121       m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
0122    }
0123 
0124    winapi_named_condition_any(open_only_t, const wchar_t *name)
0125       : m_condition_data()
0126    {
0127       named_cond_callbacks callbacks(m_condition_data.get_members());
0128       m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
0129    }
0130 
0131    #endif   //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0132 
0133    ~winapi_named_condition_any()
0134    {
0135       named_cond_callbacks callbacks(m_condition_data.get_members());
0136       m_named_sync.close(callbacks);
0137    }
0138 
0139    void notify_one()
0140    {  m_condition_data.notify_one();   }
0141 
0142    void notify_all()
0143    {  m_condition_data.notify_all();   }
0144 
0145    template <typename L, typename TimePoint>
0146    bool timed_wait(L& lock, const TimePoint &abs_time)
0147    {  return m_condition_data.timed_wait(lock, abs_time);   }
0148 
0149    template <typename L, typename TimePoint, typename Pr>
0150    bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
0151    {  return m_condition_data.timed_wait(lock, abs_time, pred);   }
0152 
0153    template <typename L>
0154    void wait(L& lock)
0155    {  m_condition_data.wait(lock);   }
0156 
0157    template <typename L, typename Pr>
0158    void wait(L& lock, Pr pred)
0159    {  m_condition_data.wait(lock, pred);   }
0160 
0161    template <typename L, class TimePoint>
0162    cv_status wait_until(L& lock, const TimePoint &abs_time)
0163    {  return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
0164 
0165    template <typename L, class TimePoint, typename Pr>
0166    bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
0167    {  return this->timed_wait(lock, abs_time, pred); }
0168 
0169    template <typename L, class Duration>
0170    cv_status wait_for(L& lock, const Duration &dur)
0171    {  return this->wait_until(lock, ipcdetail::duration_to_ustime(dur)); }
0172 
0173    template <typename L, class Duration, typename Pr>
0174    bool wait_for(L& lock, const Duration &dur, Pr pred)
0175    {  return this->wait_until(lock, ipcdetail::duration_to_ustime(dur), pred); }
0176 
0177    static bool remove(const char *name)
0178    {  return windows_named_sync::remove(name);  }
0179 
0180    static bool remove(const wchar_t *name)
0181    {  return windows_named_sync::remove(name);  }
0182 
0183    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0184    private:
0185 
0186    void dont_close_on_destruction()
0187    {}
0188 
0189    friend class interprocess_tester;
0190 
0191    struct condition_data
0192    {
0193       typedef boost::int32_t           integer_type;
0194       typedef winapi_semaphore_wrapper semaphore_type;
0195       typedef winapi_mutex_wrapper     mutex_type;
0196 
0197       integer_type    &get_nwaiters_blocked()
0198       {  return m_nwaiters_blocked;  }
0199 
0200       integer_type    &get_nwaiters_gone()
0201       {  return m_nwaiters_gone;  }
0202 
0203       integer_type    &get_nwaiters_to_unblock()
0204       {  return m_nwaiters_to_unblock;  }
0205 
0206       semaphore_type  &get_sem_block_queue()
0207       {  return m_sem_block_queue;  }
0208 
0209       semaphore_type  &get_sem_block_lock()
0210       {  return m_sem_block_lock;  }
0211 
0212       mutex_type      &get_mtx_unblock_lock()
0213       {  return m_mtx_unblock_lock;  }
0214 
0215       integer_type               m_nwaiters_blocked;
0216       integer_type               m_nwaiters_gone;
0217       integer_type               m_nwaiters_to_unblock;
0218       winapi_semaphore_wrapper   m_sem_block_queue;
0219       winapi_semaphore_wrapper   m_sem_block_lock;
0220       winapi_mutex_wrapper       m_mtx_unblock_lock;
0221    };
0222 
0223 
0224    class named_cond_callbacks : public windows_named_sync_interface
0225    {
0226       typedef __int64 sem_count_t;
0227       mutable sem_count_t sem_counts [2];
0228 
0229       public:
0230       named_cond_callbacks(condition_data &cond_data)
0231          : m_condition_data(cond_data)
0232       {}
0233 
0234       virtual std::size_t get_data_size() const BOOST_OVERRIDE
0235       {  return sizeof(sem_counts);   }
0236 
0237       virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
0238       {
0239          sem_counts[0] = m_condition_data.m_sem_block_queue.value();
0240          sem_counts[1] = m_condition_data.m_sem_block_lock.value();
0241          return &sem_counts;
0242       }
0243 
0244       virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
0245       {
0246          sem_counts[0] = 0;
0247          sem_counts[1] = 1;
0248          return &sem_counts;
0249       }
0250 
0251       virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
0252       {  return &sem_counts; }
0253 
0254       virtual bool open(create_enum_t op, const char *id_name) BOOST_OVERRIDE
0255       {  return this->open_impl(op, id_name);   }
0256 
0257       virtual bool open(create_enum_t op, const wchar_t *id_name) BOOST_OVERRIDE
0258       {  return this->open_impl(op, id_name);   }
0259 
0260       virtual void close() BOOST_OVERRIDE
0261       {
0262          m_condition_data.m_sem_block_queue.close();
0263          m_condition_data.m_sem_block_lock.close();
0264          m_condition_data.m_mtx_unblock_lock.close();
0265          m_condition_data.m_nwaiters_blocked = 0;
0266          m_condition_data.m_nwaiters_gone = 0;
0267          m_condition_data.m_nwaiters_to_unblock = 0;
0268       }
0269 
0270       virtual ~named_cond_callbacks() BOOST_OVERRIDE
0271       {}
0272 
0273       private:
0274 
0275       template<class CharT>
0276       bool open_impl(create_enum_t, const CharT *id_name)
0277       {
0278          typedef named_cond_callbacks_str<CharT> str_t;
0279          m_condition_data.m_nwaiters_blocked = 0;
0280          m_condition_data.m_nwaiters_gone = 0;
0281          m_condition_data.m_nwaiters_to_unblock = 0;
0282 
0283          //Now open semaphores and mutex.
0284          //Use local variables + swap to guarantee consistent
0285          //initialization and cleanup in case any opening fails
0286          permissions perm;
0287          perm.set_unrestricted();
0288          std::basic_string<CharT> aux_str  = str_t::ipc_cond();
0289          aux_str += id_name;
0290          std::size_t pos = aux_str.size();
0291 
0292          //sem_block_queue
0293          aux_str += str_t::bq();
0294          winapi_semaphore_wrapper sem_block_queue;
0295          bool created;
0296          if(!sem_block_queue.open_or_create
0297             (aux_str.c_str(), static_cast<long>(sem_counts[0]), winapi_semaphore_wrapper::MaxCount, perm, created))
0298             return false;
0299          aux_str.erase(pos);
0300 
0301          //sem_block_lock
0302          aux_str += str_t::bl();
0303          winapi_semaphore_wrapper sem_block_lock;
0304          if(!sem_block_lock.open_or_create
0305             (aux_str.c_str(), static_cast<long>(sem_counts[1]), winapi_semaphore_wrapper::MaxCount, perm, created))
0306             return false;
0307          aux_str.erase(pos);
0308 
0309          //mtx_unblock_lock
0310          aux_str += str_t::ul();
0311          winapi_mutex_wrapper mtx_unblock_lock;
0312          if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
0313             return false;
0314 
0315          //All ok, commit data
0316          m_condition_data.m_sem_block_queue.swap(sem_block_queue);
0317          m_condition_data.m_sem_block_lock.swap(sem_block_lock);
0318          m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
0319          return true;
0320       }
0321 
0322       condition_data &m_condition_data;
0323    };
0324 
0325    windows_named_sync   m_named_sync;
0326    ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
0327    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0328 };
0329 
0330 }  //namespace ipcdetail {
0331 }  //namespace interprocess {
0332 }  //namespace boost {
0333 
0334 #include <boost/interprocess/detail/config_end.hpp>
0335 
0336 #endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP