PLplot  5.11.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
wxwidgets_comms.cpp
Go to the documentation of this file.
1 // Copyright (C) 2008 Werner Smekal
2 //
3 // This file is part of PLplot.
4 //
5 // PLplot is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Library General Public License as published
7 // by the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // PLplot is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Library General Public License for more details.
14 //
15 // You should have received a copy of the GNU Library General Public License
16 // along with PLplot; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //
19 
20 #include "wxwidgets_comms.h"
21 #include <assert.h>
22 
23 //--------------------------------------------------------------------------
24 // Constructor, creates the object but does not actually create or link to
25 // any shared memory.
26 //--------------------------------------------------------------------------
28 {
29 #ifdef WIN32
30  m_mapFile = NULL;
31 #else
32  m_mapFile = -1;
33  m_name = NULL;
34 #endif
35  m_buffer = NULL;
36  m_size = 0;
37 }
38 
39 //--------------------------------------------------------------------------
40 // Constructor, creates the shared memory area. If onlyIfExists is true
41 // then we will try to access an existing shared memory area rather than
42 // creating a new one.
43 //--------------------------------------------------------------------------
44 PLMemoryMap::PLMemoryMap( const char *name, PLINT size, bool mustExist, bool mustNotExist )
45 {
46 #ifdef WIN32
47  m_mapFile = NULL;
48 #else
49  m_mapFile = -1;
50  m_name = NULL;
51 #endif
52  m_buffer = NULL;
53  m_size = 0;
54  create( name, size, mustExist, mustNotExist );
55 }
56 
57 //--------------------------------------------------------------------------
58 // create does most of the work in trying to create the memory map it is
59 // called by the constructor or by the user. If the object already has a
60 // shared memory area then that is closed before a new area of memory is
61 // created or connected to. As per the constructor if onlyIfExists is true
62 // then we will try to access an existing shared memory area rather than
63 // creating a new one.
64 //--------------------------------------------------------------------------
65 void PLMemoryMap::create( const char *name, PLINT size, bool mustExist, bool mustNotExist )
66 {
67  close();
68  assert( !( mustExist && mustNotExist ) );
69  if ( mustExist && mustNotExist )
70  return;
71 #ifdef WIN32
72  if ( mustExist )
73  m_mapFile = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, name );
74  else if ( mustNotExist )
75  {
76  m_mapFile = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL,
77  PAGE_READWRITE, 0, size, name );
78  if ( GetLastError() == ERROR_ALREADY_EXISTS )
79  close();
80  }
81  else
82  m_mapFile = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL,
83  PAGE_READWRITE, 0, size, name );
84 
85  if ( m_mapFile )
86  m_buffer = MapViewOfFile( m_mapFile, FILE_MAP_ALL_ACCESS, 0, 0, size );
87 #else
88  if ( mustExist )
89  m_mapFile = shm_open( name, O_RDWR, 0 );
90  else if ( mustNotExist )
91  {
92  m_mapFile = shm_open( name, O_RDWR | O_CREAT | O_EXCL, S_IRWXU ); //S_IRWXU gives user wrx permissions
93  if ( ftruncate( m_mapFile, size ) == -1 )
94  close( );
95  }
96  else
97  {
98  m_mapFile = shm_open( name, O_RDWR | O_CREAT, S_IRWXU ); //S_IRWXU gives user wrx permissions
99  if ( ftruncate( m_mapFile, size ) == -1 )
100  close( );
101  }
102  if ( m_mapFile != -1 )
103  {
104  m_buffer = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_mapFile, 0 );
105  m_name = new char[strlen( name ) + 1];
106  strcpy( m_name, name );
107  }
108 #endif
109  if ( isValid() )
110  m_size = size;
111 }
112 
113 //--------------------------------------------------------------------------
114 // Close an area of mapped memory. When all processes have closed their
115 // connections the area will be removed by the OS.
116 //--------------------------------------------------------------------------
118 {
119 #ifdef WIN32
120  if ( m_buffer )
121  UnmapViewOfFile( m_buffer );
122  if ( m_mapFile )
123  CloseHandle( m_mapFile );
124  m_mapFile = NULL;
125 #else
126  if ( m_buffer )
127  munmap( m_buffer, m_size );
128  if ( m_mapFile != -1 )
129  shm_unlink( m_name );
130  if ( m_name )
131  delete[] m_name;
132  m_mapFile = -1;
133  m_name = NULL;
134 #endif
135  m_buffer = NULL;
136  m_size = 0;
137 }
138 
139 //--------------------------------------------------------------------------
140 // Destructor, closes the connection to the mapped memory.
141 //--------------------------------------------------------------------------
143 {
144  close();
145 }
146 
147 
149 {
150  m_mutex = NULL;
151  m_haveLock = false;
152 }
153 
154 PLNamedMutex::PLNamedMutex( const char *name, bool aquireOnCreate )
155 {
156  m_mutex = NULL;
157  m_haveLock = false;
158  create( name, aquireOnCreate );
159 }
160 
161 void PLNamedMutex::create( const char *name, bool aquireOnCreate )
162 {
163 #ifdef WIN32
164  m_mutex = CreateMutexA( NULL, aquireOnCreate ? TRUE : FALSE, name );
165 #else
166  m_mutex = NULL;
167  char mutexName[251];
168  mutexName[0] = '/';
169  strncpy( mutexName + 1, name, 250 );
170  mutexName[250] = '\0';
171  m_mutex = sem_open( mutexName, O_CREAT, S_IRWXU, 1 );
172 #endif
173 }
174 
176 {
177 #ifdef WIN32
178  DWORD result = WaitForSingleObject( m_mutex, INFINITE );
179  m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
180 #else
181  m_haveLock = sem_wait( m_mutex ) == 0;
182  int result = errno;
183 #endif
184  if ( !m_haveLock )
185  throw( result );
186 }
187 
188 bool PLNamedMutex::aquire( unsigned long millisecs )
189 {
190 #ifdef WIN32
191  DWORD result = WaitForSingleObject( m_mutex, millisecs );
192  m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
193 #else
194 #endif
195  return m_haveLock;
196 }
197 
199 {
200 #ifdef WIN32
201  m_haveLock = ( WAIT_OBJECT_0 == WaitForSingleObject( m_mutex, 0 ) );
202 #else
203  m_haveLock = sem_trywait( m_mutex ) == 0;
204 #endif
205  return m_haveLock;
206 }
207 
209 {
210  if ( !m_haveLock )
211  return;
212 #ifdef WIN32
213  if ( m_mutex )
214  ReleaseMutex( m_mutex );
215 #else
216  sem_post( m_mutex );
217 #endif
218  m_haveLock = false;
219 }
220 
222 {
223  release();
224 #ifdef WIN32
225  CloseHandle( m_mutex );
226 #else
227  sem_close( m_mutex );
228 #endif
229 }
230 
232 {
233  clear();
234 }
235 
237 {
238  m_mutex = mutex;
239  m_mutex->aquire();
240 }
241 
243 {
244  return m_mutex != NULL;
245 }
246 
248 {
249  m_mutex->release();
250  m_mutex = NULL;
251 }