• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
12 #define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
13 
14 #ifndef BOOST_CONFIG_HPP
15 #  include <boost/config.hpp>
16 #endif
17 #
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 #  pragma once
20 #endif
21 
22 #include <boost/interprocess/detail/config_begin.hpp>
23 #include <boost/interprocess/detail/workaround.hpp>
24 #include <boost/interprocess/creation_tags.hpp>
25 #include <boost/interprocess/permissions.hpp>
26 #include <boost/interprocess/detail/win32_api.hpp>
27 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
28 #include <boost/interprocess/sync/windows/winapi_wrapper_common.hpp>
29 #include <boost/interprocess/errors.hpp>
30 #include <boost/interprocess/exceptions.hpp>
31 #include <limits>
32 
33 namespace boost {
34 namespace interprocess {
35 namespace ipcdetail {
36 
37 class winapi_semaphore_functions
38 {
39    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
40 
41    //Non-copyable
42    winapi_semaphore_functions(const winapi_semaphore_functions &);
43    winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
44    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
45 
46    public:
winapi_semaphore_functions(void * hnd)47    winapi_semaphore_functions(void *hnd)
48       : m_sem_hnd(hnd)
49    {}
50 
post(long count=1)51    void post(long count = 1)
52    {
53       long prev_count;
54       winapi::release_semaphore(m_sem_hnd, count, &prev_count);
55    }
56 
wait()57    void wait()
58    {  return winapi_wrapper_wait_for_single_object(m_sem_hnd);  }
59 
try_wait()60    bool try_wait()
61    {  return winapi_wrapper_try_wait_for_single_object(m_sem_hnd);  }
62 
timed_wait(const boost::posix_time::ptime & abs_time)63    bool timed_wait(const boost::posix_time::ptime &abs_time)
64    {  return winapi_wrapper_timed_wait_for_single_object(m_sem_hnd, abs_time);  }
65 
value() const66    long value() const
67    {
68       long l_count, l_limit;
69       if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
70          return 0;
71       return l_count;
72    }
73 
limit() const74    long limit() const
75    {
76       long l_count, l_limit;
77       if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
78          return 0;
79       return l_limit;
80    }
81 
82    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
83    protected:
84    void *m_sem_hnd;
85    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
86 };
87 
88 
89 //Swappable semaphore wrapper
90 class winapi_semaphore_wrapper
91    : public winapi_semaphore_functions
92 {
93    winapi_semaphore_wrapper(const winapi_semaphore_wrapper &);
94    winapi_semaphore_wrapper &operator=(const winapi_semaphore_wrapper &);
95 
96    public:
97 
98    //Long is 32 bits in windows
99    static const long MaxCount = long(0x7FFFFFFF);
100 
winapi_semaphore_wrapper(void * hnd=winapi::invalid_handle_value)101    winapi_semaphore_wrapper(void *hnd = winapi::invalid_handle_value)
102       : winapi_semaphore_functions(hnd)
103    {}
104 
~winapi_semaphore_wrapper()105    ~winapi_semaphore_wrapper()
106    {  this->close(); }
107 
release()108    void *release()
109    {
110       void *hnd = m_sem_hnd;
111       m_sem_hnd = winapi::invalid_handle_value;
112       return hnd;
113    }
114 
handle() const115    void *handle() const
116    {  return m_sem_hnd; }
117 
open_or_create(const char * name,long sem_count,long max_count,const permissions & perm,bool & created)118    bool open_or_create( const char *name
119                       , long sem_count
120                       , long max_count
121                       , const permissions &perm
122                       , bool &created)
123    {
124       if(m_sem_hnd == winapi::invalid_handle_value){
125          m_sem_hnd = winapi::open_or_create_semaphore
126             ( name
127             , sem_count
128             , max_count
129             , (winapi::interprocess_security_attributes*)perm.get_permissions()
130             );
131          created = winapi::get_last_error() != winapi::error_already_exists;
132          return m_sem_hnd != winapi::invalid_handle_value;
133       }
134       else{
135          return false;
136       }
137    }
138 
open_semaphore(const char * name)139    bool open_semaphore(const char *name)
140    {
141       if(m_sem_hnd == winapi::invalid_handle_value){
142          m_sem_hnd = winapi::open_semaphore(name);
143          return m_sem_hnd != winapi::invalid_handle_value;
144       }
145       else{
146          return false;
147       }
148    }
149 
close()150    void close()
151    {
152       if(m_sem_hnd != winapi::invalid_handle_value){
153          winapi::close_handle(m_sem_hnd);
154          m_sem_hnd = winapi::invalid_handle_value;
155       }
156    }
157 
swap(winapi_semaphore_wrapper & other)158    void swap(winapi_semaphore_wrapper &other)
159    {  void *tmp = m_sem_hnd; m_sem_hnd = other.m_sem_hnd; other.m_sem_hnd = tmp;   }
160 };
161 
162 }  //namespace ipcdetail {
163 }  //namespace interprocess {
164 }  //namespace boost {
165 
166 #include <boost/interprocess/detail/config_end.hpp>
167 
168 #endif   //BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
169