File: wxwidgets_comms.h

package info (click to toggle)
plplot 5.14.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 30,424 kB
  • sloc: ansic: 79,613; xml: 28,583; cpp: 20,037; ada: 19,456; tcl: 12,081; f90: 11,423; ml: 7,276; java: 6,863; python: 6,792; sh: 3,185; perl: 828; lisp: 75; makefile: 48; sed: 33; fortran: 5
file content (259 lines) | stat: -rw-r--r-- 8,808 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// Copyright (C) 2015-2017 Phil Rosenberg
// Copyright (C) 2017 Alan W. Irwin
// Copyright (C) 2008 Werner Smekal

// This file is part of PLplot.
//
// PLplot is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published
// by the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PLplot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with PLplot; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//

#ifndef __PL_WXWIDGETS_COMMS__
#define __PL_WXWIDGETS_COMMS__

#include "plplotP.h"
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <errno.h>
#endif

#include <wx/font.h>
#include "wxPLplot_nanosec.h"

//data transmission codes
const unsigned char transmissionRegular          = 0;
const unsigned char transmissionSkipFileEnd      = 1;
const unsigned char transmissionEndOfPage        = 2;
const unsigned char transmissionBeginPage        = 3;
const unsigned char transmissionLocate           = 4;
const unsigned char transmissionPartial          = 5;
const unsigned char transmissionComplete         = 6;
const unsigned char transmissionRequestTextSize  = 7;
const unsigned char transmissionEndOfPageNoPause = 8;
const unsigned char transmissionClose            = 9;
#ifdef PL_WXWIDGETS_IPC3
const unsigned char transmissionFlush = 10;
#endif

#define TEXTSIZEINFO_MAX_LENGTH    500

struct TextSizeInfo
{
    long         width;
    long         height;
    long         depth;
    long         leading;
    wxFontFamily family;
    int          style;
    int          weight;
    int          pt;
    bool         underlined;
    wchar_t      text[TEXTSIZEINFO_MAX_LENGTH + 1];
    bool         written;
};

struct MemoryMapHeader
{
    size_t        viewerOpenFlag;
    size_t        locateModeFlag;
    size_t        completeFlag;
#ifdef PL_WXWIDGETS_IPC3
    size_t        plbufAmountToTransmit;
    unsigned char transmissionType;
#else
    size_t        readLocation;
    size_t        writeLocation;
#endif
    PLGraphicsIn  graphicsIn;
    TextSizeInfo  textSizeInfo;
};

#ifdef PL_WXWIDGETS_IPC3
// Tuned such that total length of time to do all 35 C examples
// (except for 17 and 20) with PLPLOT_WX_NOPLOT #defined in
// utils/wxplframe.cpp is not increased significantly beyond the
// measurement noise of ~2 per cent between identical runs.  In fact
// sizes of 1024*1024 and 1024 were not different by more than the ~2
// per cent measurement noise and a size of 128 was only ~4 per cent
// larger than 1024.  So 10 * 1024 should already be gross overkill.
#define PL_SHARED_ARRAY_SIZE    10 * 1024

// In the three-semaphores method of IPC, the shared memory area must
// correspond to this shmbuf struct which contains some control data
// explicitly used for the communication, e.g., at least the total
// number of bytes of data to be transferred, and limited size
// data areas to be transferred under three-semaphore control.
struct shmbuf
{
    size_t          nbytes;           // Total number of data bytes to be transferred
    // header data to be transferred under three-semaphore control.
    MemoryMapHeader header;
    // plbuf data to be transferred under three-semaphore control.
    char            data[PL_SHARED_ARRAY_SIZE];
};

class PLThreeSemaphores
{
public:
    // Default constructor: Initialize m_wsem, m_rsem, and m_tsem to
    // NULL to mark those as invalid semaphore locations.
    PLThreeSemaphores();
    // Named semaphores.
    // Create three semaphore names from basename, and open and (only
    // on creation which happens automatically for both the Windows
    // and POSIX API cases) initialize the corresponding named
    // semaphores with the read and write semaphores initially blocked
    // and the transmit semaphore initially unblocked.
    void initializeToValid( const char * baseName );
    // call initializeToInvalid.
    ~PLThreeSemaphores();
    // If the m_wsem, m_rsem, and m_tsem locations are non-NULL
    // destroy those semaphores.  Also, unconditionally set
    // m_wsem, m_rsem, and m_tsem to NULL to mark those as invalid
    // semaphore locations.
    void initializeToInvalid();
    bool isWriteSemaphoreValid();
    bool isReadSemaphoreValid();
    bool isTransmitSemaphoreValid();
    // Return true if all semaphores are valid.
    // Return false if all semaphores are invalid.
    // Throw an exception otherwise.
    bool areSemaphoresValid();
    // Check whether write and read semaphores are valid and blocked.
    bool areWriteReadSemaphoresBlocked();
#ifndef _WIN32
    // Get value of Write semaphore.
    int getValueWriteSemaphore();
    // Get value of Read semaphore.
    int getValueReadSemaphore();
#endif // #ifndef _WIN32
    void postWriteSemaphore();
    void postReadSemaphore();
    void postTransmitSemaphore();
    void waitWriteSemaphore();
    void waitReadSemaphore();
    void waitTransmitSemaphore();
private:
    // Attempts to test semaphore initialization validity using
    // sem_getvalue on Linux proved fruitless since as far as I can tell
    // with gdb that function always returns zero, i.e., always signals
    // success, and returns a 0 or 1 value argument ___so long as its
    // sem_t * argument points to _any_ accessible memory area that is
    // cast to sem_t *__!  So here is the alternative plan we are using:
    // m_wsem, m_rsem, and m_tsem should always be NULL unless the non-NULL
    // locations they point to are properly initialized semaphores.
#define PL_SEMAPHORE_NAME_LENGTH    250 // Maximum length excluding terminating NULL byte
    char m_wsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
    char m_rsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
    char m_tsemName[PL_SEMAPHORE_NAME_LENGTH + 1];
#ifdef _WIN32
    // Windows named semaphores.
    HANDLE m_wsem;
    HANDLE m_rsem;
    HANDLE m_tsem;
#else // #ifdef _WIN32
      // POSIX named semaphores.
    sem_t *m_wsem;
    sem_t *m_rsem;
    sem_t *m_tsem;
#endif // #ifdef _WIN32
};

#endif //#ifdef PL_WXWIDGETS_IPC3

const PLINT plMemoryMapReservedSpace = sizeof ( MemoryMapHeader );

class PLMemoryMap
{
public:
    PLMemoryMap();
    PLMemoryMap( const char *name, PLINT size, bool mustExist, bool mustNotExist );
    void create( const char *name, PLINT size, bool mustExist, bool mustNotExist );
    void close();
    ~PLMemoryMap();
    bool isValid() { return m_buffer != NULL; }
#ifdef PL_WXWIDGETS_IPC3
    char *getBuffer() { return ( (shmbuf *) m_buffer )->data; }
    MemoryMapHeader *getHeader() { return &( ( (shmbuf *) m_buffer )->header ); }
    void initializeSemaphoresToValid( const char *baseName ) { m_threeSemaphores.initializeToValid( baseName ); }
    size_t *getTotalDataBytes() { return &( ( (shmbuf *) m_buffer )->nbytes ); }
    size_t getSize() { return PL_SHARED_ARRAY_SIZE; }
    void transmitBytes( bool ifHeader, const void *src, size_t n );
    void receiveBytes( bool ifHeader, void *dest, size_t n );
#else // #ifdef PL_WXWIDGETS_IPC3
    char *getBuffer() { return (char *) m_buffer; }
    size_t getSize() { return m_size; }
#endif // #ifdef PL_WXWIDGETS_IPC3
private:
#ifdef _WIN32
    HANDLE m_mapFile;
#else
    int m_mapFile;
    char * m_name;
#endif
#ifdef PL_WXWIDGETS_IPC3
    // instantiate m_threeSemaphores private object (with default
    // constructor) when PLMemoryMap is instantiated.
    PLThreeSemaphores m_threeSemaphores;
#endif
    // Size of shared memory buffer
    size_t m_size;
    void   *m_buffer;
};

#ifndef PL_WXWIDGETS_IPC3

class PLNamedMutex
{
public:
    PLNamedMutex();
    ~PLNamedMutex();
    PLNamedMutex( const char *name, bool aquireOnCreate = false );
    void create( const char *name, bool aquireOnCreate = false );
    void clear();
    void aquire();
    bool aquire( unsigned long millisecs );
    bool aquireNoWait();
    void release();
    bool isValid();
private:
    bool   m_haveLock;
#ifdef _WIN32
    HANDLE m_mutex;
#else
    sem_t  * m_mutex;
    char   m_mutexName[251];
#endif
};

class PLNamedMutexLocker
{
public:
    PLNamedMutexLocker( PLNamedMutex *mutex );
    ~PLNamedMutexLocker();
private:
    PLNamedMutex *m_mutex;
    //remove default constructors
    PLNamedMutexLocker();
    PLNamedMutexLocker( const PLNamedMutexLocker & );
    PLNamedMutexLocker & operator =( const PLNamedMutex & );
};
#endif //ifndef PL_WXWIDGETS_IPC3

#endif