PLplot  5.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
wxwidgets_comms.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015 Phil Rosenberg
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  {
90  m_mapFile = shm_open( name, O_RDWR, 0 );
91  }
92  else if ( mustNotExist )
93  {
94  m_mapFile = shm_open( name, O_RDWR | O_CREAT | O_EXCL, S_IRWXU ); //S_IRWXU gives user wrx permissions
95  if ( ftruncate( m_mapFile, size ) == -1 )
96  close( );
97  }
98  else
99  {
100  m_mapFile = shm_open( name, O_RDWR | O_CREAT, S_IRWXU ); //S_IRWXU gives user wrx permissions
101  if ( ftruncate( m_mapFile, size ) == -1 )
102  close( );
103  }
104  if ( m_mapFile != -1 )
105  {
106  m_buffer = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_mapFile, 0 );
107  m_name = new char[strlen( name ) + 1];
108  strcpy( m_name, name );
109  }
110 #endif
111  if ( isValid() )
112  m_size = size;
113 }
114 
115 //--------------------------------------------------------------------------
116 // Close an area of mapped memory. When all processes have closed their
117 // connections the area will be removed by the OS.
118 //--------------------------------------------------------------------------
120 {
121 #ifdef WIN32
122  if ( m_buffer )
123  UnmapViewOfFile( m_buffer );
124  if ( m_mapFile )
125  CloseHandle( m_mapFile );
126  m_mapFile = NULL;
127 #else
128  if ( m_buffer )
129  {
130  munmap( m_buffer, m_size );
131  }
132  if ( m_mapFile != -1 )
133  {
134  shm_unlink( m_name );
135  }
136  if ( m_name )
137  {
138  delete[] m_name;
139  }
140  m_mapFile = -1;
141  m_name = NULL;
142 
143 #endif
144  m_buffer = NULL;
145  m_size = 0;
146 }
147 
148 //--------------------------------------------------------------------------
149 // Destructor, closes the connection to the mapped memory.
150 //--------------------------------------------------------------------------
152 {
153  close();
154 }
155 
156 
158 {
159  m_mutex = NULL;
160  m_haveLock = false;
161 }
162 
163 PLNamedMutex::PLNamedMutex( const char *name, bool aquireOnCreate )
164 {
165  m_mutex = NULL;
166  m_haveLock = false;
167  create( name, aquireOnCreate );
168 }
169 
170 void PLNamedMutex::create( const char *name, bool aquireOnCreate )
171 {
172 #ifdef WIN32
173  m_mutex = CreateMutexA( NULL, aquireOnCreate ? TRUE : FALSE, name );
174 #else
175  m_mutex = NULL;
176  char mutexName[251];
177  mutexName[0] = '/';
178  strncpy( mutexName + 1, name, 250 );
179  mutexName[250] = '\0';
180  m_mutex = sem_open( mutexName, O_CREAT, S_IRWXU, 1 );
181 #endif
182 }
183 
185 {
186 #ifdef WIN32
187  DWORD result = WaitForSingleObject( m_mutex, INFINITE );
188  m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
189 #else
190  m_haveLock = sem_wait( m_mutex ) == 0;
191  int result = errno;
192 #endif
193  if ( !m_haveLock )
194  throw( result );
195 }
196 
197 bool PLNamedMutex::aquire( unsigned long millisecs )
198 {
199 #ifdef WIN32
200  DWORD result = WaitForSingleObject( m_mutex, millisecs );
201  m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
202 #else
203 #endif
204  return m_haveLock;
205 }
206 
208 {
209 #ifdef WIN32
210  m_haveLock = ( WAIT_OBJECT_0 == WaitForSingleObject( m_mutex, 0 ) );
211 #else
212  m_haveLock = sem_trywait( m_mutex ) == 0;
213 #endif
214  return m_haveLock;
215 }
216 
218 {
219  if ( !m_haveLock )
220  return;
221 #ifdef WIN32
222  if ( m_mutex )
223  ReleaseMutex( m_mutex );
224 #else
225  sem_post( m_mutex );
226 #endif
227  m_haveLock = false;
228 }
229 
231 {
232  release();
233 #ifdef WIN32
234  CloseHandle( m_mutex );
235 #else
236  sem_close( m_mutex );
237 #endif
238 }
239 
241 {
242  clear();
243 }
244 
246 {
247  m_mutex = mutex;
248  m_mutex->aquire();
249 }
250 
252 {
253  return m_mutex != NULL;
254 }
255 
257 {
258  m_mutex->release();
259  m_mutex = NULL;
260 }
static const char * name
Definition: tkMain.c:135
PLNamedMutex * m_mutex
int PLINT
Definition: plplot.h:174
void create(const char *name, bool aquireOnCreate=false)
#define TRUE
Definition: plplotP.h:176
#define FALSE
Definition: plplotP.h:177
void create(const char *name, PLINT size, bool mustExist, bool mustNotExist)