glooxd  0.3-svn
semafore.cpp
1 /*
2  Copyright (c) 2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the glooxd library. http://camaya.net/glooxd
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #include "semafore.h"
15 
16 #if !defined( _WIN32 ) && !defined( _WIN32_WCE )
17 # include "config.h"
18 #endif
19 
20 #ifdef _WIN32
21 # include <windows.h>
22 #endif
23 
24 #ifdef _WIN32_WCE
25 # include <winbase.h>
26 #endif
27 
28 #if defined(__APPLE__) && defined(__MACH__)
29  // NOTE: On Mac OS, unnamed semaphores are not implemented,
30  // even though the headers are all there.
31  // So, we'll use the native Mach type.
32 # include <mach/mach_init.h>
33 # include <mach/semaphore.h>
34 # include <mach/task.h>
35 #elif defined(HAVE_PTHREAD)
36 # include <semaphore.h>
37 #endif
38 
39 #include <stdio.h>
40 
41 namespace glooxd
42 {
43 
44  namespace util
45  {
46 
47  class Semaphore::SemaphoreImpl
48  {
49  public:
50  SemaphoreImpl( int value );
51  ~SemaphoreImpl();
52  void wait();
53  bool trywait();
54  void post();
55  private:
56  SemaphoreImpl( const SemaphoreImpl& );
57  SemaphoreImpl& operator=( const SemaphoreImpl& );
58 
59 #ifdef _WIN32
60  HANDLE m_semaphore;
61 #elif defined(__APPLE__) && defined(__MACH__)
62  semaphore_t m_semaphore;
63 #elif defined( HAVE_PTHREAD )
64  sem_t m_semaphore;
65 #endif
66 
67  };
68 
69  Semaphore::SemaphoreImpl::SemaphoreImpl( int value )
70  {
71 #ifdef _WIN32
72  m_semaphore = CreateSemaphore( 0, 0, 123456, 0 );
73 #elif defined(__APPLE__) && defined(__MACH__)
74  kern_return_t result = semaphore_create( mach_task_self(), &m_semaphore, SYNC_POLICY_FIFO, value );
75  if( result != KERN_SUCCESS )
76  {
77 #ifdef DEBUG
78  printf( "Semaphore::SemaphoreImpl() call to semaphore_create failed: %d\n", result );
79 #endif
80  }
81 #elif defined( HAVE_PTHREAD )
82  int result = sem_init( &m_semaphore, 0, value );
83  if( result == -1 )
84  {
85 #ifdef DEBUG
86  printf( "Semaphore::SemaphoreImpl() call to sem_init failed: %d\n", errno );
87 #endif
88  }
89 #endif
90  }
91 
92  Semaphore::SemaphoreImpl::~SemaphoreImpl()
93  {
94 #ifdef _WIN32
95  CloseHandle( m_semaphore );
96 #elif defined(__APPLE__) && defined(__MACH__)
97  semaphore_destroy( mach_task_self(), m_semaphore );
98 #elif defined( HAVE_PTHREAD )
99  sem_destroy( &m_semaphore );
100 #endif
101  }
102 
104  {
105 #ifdef _WIN32
106  WaitForSingleObject( m_semaphore, INFINITE );
107 #elif defined(__APPLE__) && defined(__MACH__)
108  semaphore_wait( m_semaphore );
109 #elif defined( HAVE_PTHREAD )
110  sem_wait( &m_semaphore );
111 #endif
112  }
113 
115  {
116 #ifdef _WIN32
117  return ( WaitForSingleObject( m_semaphore, 0 ) == WAIT_OBJECT_0 );
118 #elif defined(__APPLE__) && defined(__MACH__)
119  mach_timespec_t timeout = { 0, 0 };
120  return ( semaphore_timedwait( m_semaphore, timeout ) == KERN_SUCCESS );
121 #elif defined( HAVE_PTHREAD )
122  return !sem_trywait( &m_semaphore );
123 #endif
124  return true;
125  }
126 
128  {
129 #ifdef _WIN32
130  ReleaseSemaphore( m_semaphore, 1, 0 );
131 #elif defined(__APPLE__) && defined(__MACH__)
132  semaphore_signal( m_semaphore );
133 #elif defined( HAVE_PTHREAD )
134  sem_post( &m_semaphore );
135 #endif
136  }
137 
138  Semaphore::Semaphore( int value )
139  : m_semaphore( new SemaphoreImpl( value ) )
140  {
141  }
142 
144  {
145  delete m_semaphore;
146  }
147 
149  {
150  m_semaphore->wait();
151  }
152 
154  {
155  return m_semaphore->trywait();
156  }
157 
159  {
160  m_semaphore->post();
161  }
162 
163  }
164 
165 }