PLplot  5.15.0
wxwidgets_comms.h
Go to the documentation of this file.
1 // Copyright (C) 2015-2017 Phil Rosenberg
2 // Copyright (C) 2017 Alan W. Irwin
3 // Copyright (C) 2008 Werner Smekal
4 
5 // This file is part of PLplot.
6 //
7 // PLplot is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU Library General Public License as published
9 // by the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // PLplot is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with PLplot; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 
22 #ifndef __PL_WXWIDGETS_COMMS__
23 #define __PL_WXWIDGETS_COMMS__
24 
25 #include "plplotP.h"
26 #ifdef _WIN32
27 #include <Windows.h>
28 #else
29 #include <sys/mman.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <semaphore.h>
33 #include <errno.h>
34 #endif
35 
36 #include <wx/font.h>
37 #include "wxPLplot_nanosec.h"
38 
39 //data transmission codes
40 const unsigned char transmissionRegular = 0;
41 const unsigned char transmissionSkipFileEnd = 1;
42 const unsigned char transmissionEndOfPage = 2;
43 const unsigned char transmissionBeginPage = 3;
44 const unsigned char transmissionLocate = 4;
45 const unsigned char transmissionPartial = 5;
46 const unsigned char transmissionComplete = 6;
47 const unsigned char transmissionRequestTextSize = 7;
48 const unsigned char transmissionEndOfPageNoPause = 8;
49 const unsigned char transmissionClose = 9;
50 #ifdef PL_WXWIDGETS_IPC3
51 const unsigned char transmissionFlush = 10;
52 #endif
53 
54 #define TEXTSIZEINFO_MAX_LENGTH 500
55 
57 {
58  long width;
59  long height;
60  long depth;
61  long leading;
62  wxFontFamily family;
63  int style;
64  int weight;
65  int pt;
66  bool underlined;
68  bool written;
69 };
70 
72 {
75  size_t completeFlag;
76 #ifdef PL_WXWIDGETS_IPC3
77  size_t plbufAmountToTransmit;
78  unsigned char transmissionType;
79 #else
80  size_t readLocation;
81  size_t writeLocation;
82 #endif
85 };
86 
87 #ifdef PL_WXWIDGETS_IPC3
88 // Tuned such that total length of time to do all 35 C examples
89 // (except for 17 and 20) with PLPLOT_WX_NOPLOT #defined in
90 // utils/wxplframe.cpp is not increased significantly beyond the
91 // measurement noise of ~2 per cent between identical runs. In fact
92 // sizes of 1024*1024 and 1024 were not different by more than the ~2
93 // per cent measurement noise and a size of 128 was only ~4 per cent
94 // larger than 1024. So 10 * 1024 should already be gross overkill.
95 #define PL_SHARED_ARRAY_SIZE 10 * 1024
96 
97 // In the three-semaphores method of IPC, the shared memory area must
98 // correspond to this shmbuf struct which contains some control data
99 // explicitly used for the communication, e.g., at least the total
100 // number of bytes of data to be transferred, and limited size
101 // data areas to be transferred under three-semaphore control.
102 struct shmbuf
103 {
104  size_t nbytes; // Total number of data bytes to be transferred
105  // header data to be transferred under three-semaphore control.
107  // plbuf data to be transferred under three-semaphore control.
108  char data[PL_SHARED_ARRAY_SIZE];
109 };
110 
111 class PLThreeSemaphores
112 {
113 public:
114  // Default constructor: Initialize m_wsem, m_rsem, and m_tsem to
115  // NULL to mark those as invalid semaphore locations.
116  PLThreeSemaphores();
117  // Named semaphores.
118  // Create three semaphore names from basename, and open and (only
119  // on creation which happens automatically for both the Windows
120  // and POSIX API cases) initialize the corresponding named
121  // semaphores with the read and write semaphores initially blocked
122  // and the transmit semaphore initially unblocked.
123  void initializeToValid( const char * baseName );
124  // call initializeToInvalid.
125  ~PLThreeSemaphores();
126  // If the m_wsem, m_rsem, and m_tsem locations are non-NULL
127  // destroy those semaphores. Also, unconditionally set
128  // m_wsem, m_rsem, and m_tsem to NULL to mark those as invalid
129  // semaphore locations.
130  void initializeToInvalid();
131  bool isWriteSemaphoreValid();
132  bool isReadSemaphoreValid();
133  bool isTransmitSemaphoreValid();
134  // Return true if all semaphores are valid.
135  // Return false if all semaphores are invalid.
136  // Throw an exception otherwise.
137  bool areSemaphoresValid();
138  // Check whether write and read semaphores are valid and blocked.
139  bool areWriteReadSemaphoresBlocked();
140 #ifndef _WIN32
141  // Get value of Write semaphore.
142  int getValueWriteSemaphore();
143  // Get value of Read semaphore.
144  int getValueReadSemaphore();
145 #endif // #ifndef _WIN32
146  void postWriteSemaphore();
147  void postReadSemaphore();
148  void postTransmitSemaphore();
149  void waitWriteSemaphore();
150  void waitReadSemaphore();
151  void waitTransmitSemaphore();
152 private:
153  // Attempts to test semaphore initialization validity using
154  // sem_getvalue on Linux proved fruitless since as far as I can tell
155  // with gdb that function always returns zero, i.e., always signals
156  // success, and returns a 0 or 1 value argument ___so long as its
157  // sem_t * argument points to _any_ accessible memory area that is
158  // cast to sem_t *__! So here is the alternative plan we are using:
159  // m_wsem, m_rsem, and m_tsem should always be NULL unless the non-NULL
160  // locations they point to are properly initialized semaphores.
161 #define PL_SEMAPHORE_NAME_LENGTH 250 // Maximum length excluding terminating NULL byte
162  char m_wsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
163  char m_rsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
164  char m_tsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
165 #ifdef _WIN32
166  // Windows named semaphores.
167  HANDLE m_wsem;
168  HANDLE m_rsem;
169  HANDLE m_tsem;
170 #else // #ifdef _WIN32
171  // POSIX named semaphores.
172  sem_t *m_wsem;
173  sem_t *m_rsem;
174  sem_t *m_tsem;
175 #endif // #ifdef _WIN32
176 };
177 
178 #endif //#ifdef PL_WXWIDGETS_IPC3
179 
181 
183 {
184 public:
185  PLMemoryMap();
186  PLMemoryMap( const char *name, PLINT size, bool mustExist, bool mustNotExist );
187  void create( const char *name, PLINT size, bool mustExist, bool mustNotExist );
188  void close();
189  ~PLMemoryMap();
190  bool isValid() { return m_buffer != NULL; }
191 #ifdef PL_WXWIDGETS_IPC3
192  char *getBuffer() { return ( (shmbuf *) m_buffer )->data; }
193  MemoryMapHeader *getHeader() { return &( ( (shmbuf *) m_buffer )->header ); }
194  void initializeSemaphoresToValid( const char *baseName ) { m_threeSemaphores.initializeToValid( baseName ); }
195  size_t *getTotalDataBytes() { return &( ( (shmbuf *) m_buffer )->nbytes ); }
196  size_t getSize() { return PL_SHARED_ARRAY_SIZE; }
197  void transmitBytes( bool ifHeader, const void *src, size_t n );
198  void receiveBytes( bool ifHeader, void *dest, size_t n );
199 #else // #ifdef PL_WXWIDGETS_IPC3
200  char *getBuffer() { return (char *) m_buffer; }
201  size_t getSize() { return m_size; }
202 #endif // #ifdef PL_WXWIDGETS_IPC3
203 private:
204 #ifdef _WIN32
205  HANDLE m_mapFile;
206 #else
208  char * m_name;
209 #endif
210 #ifdef PL_WXWIDGETS_IPC3
211  // instantiate m_threeSemaphores private object (with default
212  // constructor) when PLMemoryMap is instantiated.
213  PLThreeSemaphores m_threeSemaphores;
214 #endif
215  // Size of shared memory buffer
216  size_t m_size;
217  void *m_buffer;
218 };
219 
220 #ifndef PL_WXWIDGETS_IPC3
221 
223 {
224 public:
225  PLNamedMutex();
226  ~PLNamedMutex();
227  PLNamedMutex( const char *name, bool aquireOnCreate = false );
228  void create( const char *name, bool aquireOnCreate = false );
229  void clear();
230  void aquire();
231  bool aquire( unsigned long millisecs );
232  bool aquireNoWait();
233  void release();
234  bool isValid();
235 private:
237 #ifdef _WIN32
238  HANDLE m_mutex;
239 #else
240  sem_t * m_mutex;
241  char m_mutexName[251];
242 #endif
243 };
244 
246 {
247 public:
250 private:
252  //remove default constructors
255  PLNamedMutexLocker & operator =( const PLNamedMutex & );
256 };
257 #endif //ifndef PL_WXWIDGETS_IPC3
258 
259 #endif
#define TEXTSIZEINFO_MAX_LENGTH
const char header[]
Definition: deltaT-gen.c:41
static const char * name
Definition: tkMain.c:135
TextSizeInfo textSizeInfo
const unsigned char transmissionRegular
const unsigned char transmissionLocate
char * getBuffer()
PLNamedMutex * m_mutex
size_t getSize()
const unsigned char transmissionClose
int PLINT
Definition: plplot.h:181
const PLINT plMemoryMapReservedSpace
const unsigned char transmissionComplete
const unsigned char transmissionBeginPage
const unsigned char transmissionPartial
PLGraphicsIn graphicsIn
wxFontFamily family
const unsigned char transmissionSkipFileEnd
const unsigned char transmissionRequestTextSize
wchar_t text[TEXTSIZEINFO_MAX_LENGTH+1]
const unsigned char transmissionEndOfPageNoPause
const unsigned char transmissionEndOfPage