24 #ifdef PL_WXWIDGETS_IPC3
28 PLThreeSemaphores::PLThreeSemaphores()
41 void PLThreeSemaphores::initializeToValid(
const char * baseName )
46 strcpy( m_wsemName,
"/wsem" );
47 strncpy( m_wsemName + 5, baseName, PL_SEMAPHORE_NAME_LENGTH - 5 );
48 m_wsemName[PL_SEMAPHORE_NAME_LENGTH] =
'\0';
50 strcpy( m_rsemName,
"/rsem" );
51 strncpy( m_rsemName + 5, baseName, PL_SEMAPHORE_NAME_LENGTH - 5 );
52 m_rsemName[PL_SEMAPHORE_NAME_LENGTH] =
'\0';
54 strcpy( m_tsemName,
"/tsem" );
55 strncpy( m_tsemName + 5, baseName, PL_SEMAPHORE_NAME_LENGTH - 5 );
56 m_tsemName[PL_SEMAPHORE_NAME_LENGTH] =
'\0';
60 m_wsem = CreateSemaphoreA( NULL, 0, 1, m_wsemName );
61 m_rsem = CreateSemaphoreA( NULL, 0, 1, m_rsemName );
62 m_tsem = CreateSemaphoreA( NULL, 1, 1, m_tsemName );
65 m_wsem = sem_open( m_wsemName, O_CREAT, S_IRWXU, 0 );
66 m_rsem = sem_open( m_rsemName, O_CREAT, S_IRWXU, 0 );
67 m_tsem = sem_open( m_tsemName, O_CREAT, S_IRWXU, 1 );
68 #endif // #ifdef WIN32
72 PLThreeSemaphores::~PLThreeSemaphores()
74 initializeToInvalid();
81 void PLThreeSemaphores::initializeToInvalid()
83 if ( areSemaphoresValid() )
87 CloseHandle( m_wsem );
88 CloseHandle( m_rsem );
89 CloseHandle( m_tsem );
97 sem_unlink( m_wsemName );
100 sem_unlink( m_rsemName );
103 sem_unlink( m_tsemName );
105 #endif // #ifdef WIN32
129 bool PLThreeSemaphores::isWriteSemaphoreValid()
131 return m_wsem != NULL;
134 bool PLThreeSemaphores::isReadSemaphoreValid()
136 return m_rsem != NULL;
139 bool PLThreeSemaphores::isTransmitSemaphoreValid()
141 return m_tsem != NULL;
148 bool PLThreeSemaphores::areSemaphoresValid()
150 if ( isWriteSemaphoreValid() && isReadSemaphoreValid() && isTransmitSemaphoreValid() )
154 else if ( !isWriteSemaphoreValid() && !isReadSemaphoreValid() && !isTransmitSemaphoreValid() )
159 throw(
"PLThreeSemaphores::areSemaphoresValid: invalid combination of read, write, and transmit semaphore validity" );
166 bool PLThreeSemaphores::areWriteReadSemaphoresBlocked()
168 if ( areSemaphoresValid() )
175 #else // #ifdef WIN32
185 if ( sem_getvalue( m_wsem, &wvalue ) != 0 || sem_getvalue( m_rsem, &rvalue ) != 0 )
186 throw(
"PLThreeSemaphores::areSemaphoresBlocked: sem_getvalue error on one of the write or read semaphores" );
187 if ( wvalue == 0 && rvalue == 0 )
191 #endif // #ifdef WIN32
201 int PLThreeSemaphores::getValueWriteSemaphore()
206 if ( !isWriteSemaphoreValid() )
208 throw(
"PLThreeSemaphores::getValueWriteSemaphore: attempt to get value for invalid semaphore." );
212 if ( sem_getvalue( m_wsem, &ret_value ) != 0 )
213 throw(
"PLThreeSemaphores::getValueWriteSemaphore: sem_getvalue failed" );
219 int PLThreeSemaphores::getValueReadSemaphore()
224 if ( !isReadSemaphoreValid() )
226 throw(
"PLThreeSemaphores::getValueReadSemaphore: attempt to get value for invalid semaphore." );
230 if ( sem_getvalue( m_rsem, &ret_value ) != 0 )
231 throw(
"PLThreeSemaphores::getValueReadSemaphore: sem_getvalue failed" );
235 #endif // #ifndef WIN32
237 void PLThreeSemaphores::postWriteSemaphore()
239 if ( !isWriteSemaphoreValid() )
240 throw(
"PLThreeSemaphores::postWriteSemaphore: invalid write semaphore" );
243 if ( !ReleaseSemaphore( m_wsem, 1, NULL ) )
244 throw(
"PLThreeSemaphores::postWriteSemaphore: ReleaseSemaphore failed for write semaphore" );
245 #else // #ifdef WIN32
246 if ( sem_post( m_wsem ) )
247 throw(
"PLThreeSemaphores::postWriteSemaphore: sem_post failed for write semaphore" );
248 #endif // #ifdef WIN32
251 void PLThreeSemaphores::postReadSemaphore()
253 if ( !isReadSemaphoreValid() )
254 throw(
"PLThreeSemaphores::postReadSemaphore: invalid read semaphore" );
257 if ( !ReleaseSemaphore( m_rsem, 1, NULL ) )
258 throw(
"PLThreeSemaphores::postReadSemaphore: ReleaseSemaphore failed for read semaphore" );
259 #else // #ifdef WIN32
260 if ( sem_post( m_rsem ) )
261 throw(
"PLThreeSemaphores::postReadSemaphore: sem_post failed for read semaphore" );
262 #endif // #ifdef WIN32
265 void PLThreeSemaphores::postTransmitSemaphore()
267 if ( !isTransmitSemaphoreValid() )
268 throw(
"PLThreeSemaphores::postTransmitSemaphore: invalid transmit semaphore" );
271 if ( !ReleaseSemaphore( m_tsem, 1, NULL ) )
272 throw(
"PLThreeSemaphores::postTransmitSemaphore: ReleaseSemaphore failed for transmit semaphore" );
273 #else // #ifdef WIN32
274 if ( sem_post( m_tsem ) )
275 throw(
"PLThreeSemaphores::postTransmitSemaphore: sem_post failed for transmit semaphore" );
276 #endif // #ifdef WIN32
279 void PLThreeSemaphores::waitWriteSemaphore()
281 if ( !isWriteSemaphoreValid() )
282 throw(
"PLThreeSemaphores::waitWriteSemaphore: invalid write semaphore" );
285 DWORD result = WaitForSingleObject( m_wsem, INFINITE );
286 if ( result == WAIT_FAILED )
287 throw(
"PLThreeSemaphores::waitWriteSemaphore: WaitForSingleObject failed for write semaphore" );
288 #else // #ifdef WIN32
289 if ( sem_wait( m_wsem ) )
290 throw(
"PLThreeSemaphores::waitWriteSemaphore: sem_wait failed for write semaphore" );
291 #endif // #ifdef WIN32
294 void PLThreeSemaphores::waitReadSemaphore()
296 if ( !isReadSemaphoreValid() )
297 throw(
"PLThreeSemaphores::waitReadSemaphore: invalid read semaphore" );
300 DWORD result = WaitForSingleObject( m_rsem, INFINITE );
301 if ( result == WAIT_FAILED )
302 throw(
"PLThreeSemaphores::waitReadSemaphore: WaitForSingleObject failed for read semaphore" );
303 #else // #ifdef WIN32
304 if ( sem_wait( m_rsem ) )
305 throw(
"PLThreeSemaphores::waitReadSemaphore: sem_wait failed for read semaphore" );
306 #endif // #ifdef WIN32
309 void PLThreeSemaphores::waitTransmitSemaphore()
311 if ( !isTransmitSemaphoreValid() )
312 throw(
"PLThreeSemaphores::waitTransmitSemaphore: invalid transmit semaphore" );
315 DWORD result = WaitForSingleObject( m_tsem, INFINITE );
316 if ( result == WAIT_FAILED )
317 throw(
"PLThreeSemaphores::waitTransmitSemaphore: WaitForSingleObject failed for transmit semaphore" );
318 #else // #ifdef WIN32
319 if ( sem_wait( m_tsem ) )
320 throw(
"PLThreeSemaphores::waitTransmitSemaphore: sem_wait failed for transmit semaphore" );
321 #endif // #ifdef WIN32
323 #endif //#ifdef PL_WXWIDGETS_IPC3
356 create( name, size, mustExist, mustNotExist );
370 assert( !( mustExist && mustNotExist ) );
371 if ( mustExist && mustNotExist )
376 else if ( mustNotExist )
378 m_mapFile = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL,
379 PAGE_READWRITE, 0, size, name );
380 if ( GetLastError() == ERROR_ALREADY_EXISTS )
384 m_mapFile = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL,
385 PAGE_READWRITE, 0, size, name );
394 else if ( mustNotExist )
396 m_mapFile = shm_open( name, O_RDWR | O_CREAT | O_EXCL, S_IRWXU );
397 if ( ftruncate(
m_mapFile, size ) == -1 )
402 m_mapFile = shm_open( name, O_RDWR | O_CREAT, S_IRWXU );
403 if ( ftruncate(
m_mapFile, size ) == -1 )
409 m_name =
new char[strlen( name ) + 1];
417 #ifdef PL_WXWIDGETS_IPC3
450 void PLMemoryMap::transmitBytes(
bool ifHeader,
const void *src,
size_t n )
452 size_t chunk, nbytes_chunk, transmitted_bytes;
453 const char * csrc = (
const char *) src;
454 void * hdest = (
void *) getHeader();
458 throw (
"PLMemoryMap::transmitBytes: invalid memory map" );
464 size_area = PL_SHARED_ARRAY_SIZE;
467 throw(
"PLMemoryMap::transmitBytes: ifHeader true has invalid n value" );
471 m_threeSemaphores.waitTransmitSemaphore();
473 if ( !m_threeSemaphores.areWriteReadSemaphoresBlocked() )
474 throw(
"PLMemoryMap::transmitBytes: attempt to start transfer with semaphores not in correct blocked state." );
476 m_threeSemaphores.postWriteSemaphore();
478 for ( chunk = 0, transmitted_bytes = 0;; chunk++, csrc += nbytes_chunk )
481 m_threeSemaphores.waitWriteSemaphore();
486 ( (shmbuf *)
m_buffer )->nbytes = n;
489 nbytes_chunk =
MIN( size_area, n - transmitted_bytes );
490 if ( nbytes_chunk > 0 )
493 memcpy( hdest, csrc, nbytes_chunk );
495 memcpy( bdest, csrc, nbytes_chunk );
500 m_threeSemaphores.postReadSemaphore();
502 if ( !( nbytes_chunk > 0 ) )
506 transmitted_bytes += nbytes_chunk;
511 m_threeSemaphores.waitWriteSemaphore();
515 if ( !m_threeSemaphores.areWriteReadSemaphoresBlocked() )
516 throw(
"PLMemoryMap::transmitBytes (internal error): transfer finished with write and read semaphores not in correct blocked state." );
519 m_threeSemaphores.postTransmitSemaphore();
551 void PLMemoryMap::receiveBytes(
bool ifHeader,
void *dest,
size_t n )
553 size_t chunk, nbytes, nbytes_chunk, received_bytes;
554 char * cdest = (
char *) dest;
555 void * hsrc = (
void *) getHeader();
559 throw(
"PLMemoryMap::receiveBytes: invalid memory map" );
565 size_area = PL_SHARED_ARRAY_SIZE;
568 throw(
"PLMemoryMap::receiveBytes: ifHeader true has invalid n value" );
571 m_threeSemaphores.areSemaphoresValid();
573 for ( chunk = 0, received_bytes = 0;; chunk++, cdest += nbytes_chunk )
577 m_threeSemaphores.waitReadSemaphore();
582 nbytes = ( (shmbuf *)
m_buffer )->nbytes;
584 throw (
"PLMemoryMap::receiveBytes: n too small to receive results" );
587 nbytes_chunk =
MIN( size_area, nbytes - received_bytes );
588 if ( !( nbytes_chunk > 0 ) )
594 received_bytes += nbytes_chunk;
597 memcpy( cdest, hsrc, nbytes_chunk );
599 memcpy( cdest, bsrc, nbytes_chunk );
601 m_threeSemaphores.postWriteSemaphore();
606 m_threeSemaphores.postWriteSemaphore();
613 #endif // #ifdef PL_WXWIDGETS_IPC3
655 #ifndef PL_WXWIDGETS_IPC3
667 create( name, aquireOnCreate );
686 DWORD result = WaitForSingleObject(
m_mutex, INFINITE );
687 m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
699 DWORD result = WaitForSingleObject(
m_mutex, millisecs );
700 m_haveLock = ( result == WAIT_OBJECT_0 || result == WAIT_ABANDONED );
762 #endif //#ifndef PL_WXWIDGETS_IPC3
void create(const char *name, bool aquireOnCreate=false)
void create(const char *name, PLINT size, bool mustExist, bool mustNotExist)