VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gsemaphore_sysv.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gsemaphore_sysv.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gsemaphore.h"
23 #include "gprocess.h"
24 #include <stdexcept>
25 #include <string>
26 #include <sys/ipc.h>
27 #include <sys/sem.h>
28 #include <errno.h>
29 
30 G::Semaphore * G::Semaphore::at( storage_type * p )
31 {
32  // SignalSafe
33  return reinterpret_cast<G::Semaphore*>(p) ;
34 }
35 
36 G::Semaphore::Semaphore( unsigned int initial_value )
37 {
38  int id = ::semget( IPC_PRIVATE , 1 , IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR ) ;
39  if( id < 0 )
40  throw std::runtime_error( "semget failed" ) ;
41 
42  m_storage.filler[0] = static_cast<unsigned int>(id) ;
43 
44  union { int val ; void * p ; } u ; u.val = static_cast<int>(initial_value) ;
45  int rc = ::semctl( id , 0 , SETVAL , u ) ;
46  if( rc < 0 )
47  {
48  int e = errno ;
49  throw std::runtime_error( std::string("semctl setval failed: ") + G::Process::strerror(e) ) ;
50  }
51 }
52 
54 {
55  int id = static_cast<int>( m_storage.filler[0] ) ;
56  m_storage.filler[0] = -1 ;
57  ::semctl( id , 0 , IPC_RMID ) ;
58 }
59 
61 {
62  // SignalSafe
63  int id = static_cast<int>( m_storage.filler[0] ) ;
64  struct ::sembuf op_zero ;
65  struct ::sembuf op = op_zero ;
66  op.sem_num = 0 ; // sem_num'th in the set
67  op.sem_op = 1 ;
68  op.sem_flg = 0 ;
69  ::semop( id , &op , 1 ) ;
70 }
71 
72 #ifdef G_UNIX_LINUX
73 bool G::Semaphore::decrement( int timeout )
74 {
75  int id = static_cast<int>( m_storage.filler[0] ) ;
76  struct ::sembuf op_zero ;
77  struct ::sembuf op = op_zero ;
78  op.sem_num = 0 ; // sem_num'th in the set
79  op.sem_op = -1 ;
80  op.sem_flg = 0 ;
81  struct timespec ts = { timeout , 0 } ;
82  int rc = ::semtimedop( id , &op , 1 , &ts ) ; // not in freebsd
83  if( rc < 0 && errno != EAGAIN )
84  throw std::runtime_error( "semtimedop decrement failed" ) ;
85  return rc >= 0 ;
86 }
87 #endif
88 
90 {
91  int id = static_cast<int>( m_storage.filler[0] ) ;
92  struct ::sembuf op_zero ;
93  struct ::sembuf op = op_zero ;
94  op.sem_num = 0 ; // sem_num'th in the set
95  op.sem_op = -1 ;
96  op.sem_flg = 0 ;
97  int rc = ::semop( id , &op , 1 ) ;
98  if( rc < 0 )
99  throw std::runtime_error( "semop decrement failed" ) ;
100 }
101 
102 /// \file gsemaphore_sysv.cpp
void decrement()
Decrement-but-block-if-zero operator.
static Semaphore * at(storage_type *)
Syntactic sugar to return an object pointer corresponding to the given storage pointer.
void increment()
Increment operator. Used for mutex unlocking.
A semaphore class with a posix or sysv implementation chosen at build-time.
Definition: gsemaphore.h:47
~Semaphore()
Destroys the semaphore.
Semaphore(unsigned int initial_value=1U)
Constructor for a new anonymous semaphore, typically located inside a shared memory segment using "pl...