device_mutex.h
Go to the documentation of this file.
1 #include <sys/mman.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <sys/ipc.h>
9 #include <sys/shm.h>
10 #include <errno.h>
11 #include <semaphore.h>
12 
13 typedef struct {
14  int count;
15  pid_t pid;
16 } ST_MUTEX_MEM;
17 
18 
20 {
21 public:
22  DEVICE_MUTEX( const char* shm_key, int timeout_sec=1 )
23  {
24  if( (shm_id = shmget( ftok( shm_key, 'R' ), 80, IPC_CREAT|IPC_EXCL|0666)) == -1){
25  if( errno == EEXIST ){
26  perror("exist");
27  shm_id = shmget( ftok( shm_key, 'R' ), 80, 0666);
28  perror("exis");
29  }else{
30  perror("shmget");
31  exit(-1);
32  }
33  }
34  mutex_mem = (ST_MUTEX_MEM *)shmat( shm_id, NULL, 0 );
35  // printf("debug %d %08x %d\r\n",shm_id,(void*)mutex_mem, mutex_mem->pid );
36  if( mutex_mem == (void *)-1 ){
37  perror("shmat");
38  }
39 
40  int fa;
41  for( fa=strlen(shm_key)-1 ; fa > 0 ; --fa ){
42  if( shm_key[fa] == '/' ){
43  break;
44  }
45  }
46 
47  sem = sem_open(&shm_key[fa], O_CREAT, (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH), 1);
48  lock_flg = false;
49  if( sem == SEM_FAILED ){
50  perror("semopen");
51  }
52 
53  timespec timeout;
54  clock_gettime( CLOCK_REALTIME, &timeout);
55  timeout.tv_sec += 1;
56  if( (sem_timedwait( sem, &timeout ) != 0) && (errno == ETIMEDOUT) ){
57  if( !is_alive(mutex_mem->pid) ){
58  int semval;
59  sem_getvalue( sem, &semval );
60  if( semval <= 0 ){
61  sem_post( sem );
62  }
63  mutex_mem->pid = getpid();
64  mutex_mem->count = 0;
65  }
66  }else{
67  mutex_mem->pid = getpid();
68  unlock();
69  }
70 
71  ++mutex_mem->count;
72  }
73  virtual ~DEVICE_MUTEX()
74  {
75  --mutex_mem->count;
76  if( lock_flg ){
77  unlock();
78  }
79  sem_close( sem );
80  shmdt( mutex_mem );
81  shmctl(shm_id, IPC_RMID, 0);
82  }
83  void lock()
84  {
85  sem_wait( sem );
86  mutex_mem->pid = getpid();
87  lock_flg = true;
88  }
89  void unlock()
90  {
91  sem_post( sem );
92  mutex_mem->pid = 0;
93  lock_flg = false;
94  }
95 private:
96  bool is_alive( pid_t check_pid )
97  {
98  char filepath[256];
99  struct stat get_stat;
100  snprintf( filepath, sizeof(filepath), "/proc/%d", (int)check_pid );
101  return (stat(filepath,&get_stat)==0)?true:false;
102  }
103  int shm_id;
104  int timeout;
106  sem_t* sem;
107  bool lock_flg;
108 };
109 
110 
111 
DEVICE_MUTEX::mutex_mem
ST_MUTEX_MEM * mutex_mem
Definition: device_mutex.h:105
DEVICE_MUTEX::unlock
void unlock()
Definition: device_mutex.h:89
ST_MUTEX_MEM::pid
pid_t pid
Definition: device_mutex.h:15
DEVICE_MUTEX::DEVICE_MUTEX
DEVICE_MUTEX(const char *shm_key, int timeout_sec=1)
Definition: device_mutex.h:22
DEVICE_MUTEX::lock_flg
bool lock_flg
Definition: device_mutex.h:107
DEVICE_MUTEX::lock
void lock()
Definition: device_mutex.h:83
DEVICE_MUTEX
Definition: device_mutex.h:19
ST_MUTEX_MEM::count
int count
Definition: device_mutex.h:14
DEVICE_MUTEX::is_alive
bool is_alive(pid_t check_pid)
Definition: device_mutex.h:96
ST_MUTEX_MEM
Definition: device_mutex.h:13
DEVICE_MUTEX::sem
sem_t * sem
Definition: device_mutex.h:106
DEVICE_MUTEX::~DEVICE_MUTEX
virtual ~DEVICE_MUTEX()
Definition: device_mutex.h:73
DEVICE_MUTEX::shm_id
int shm_id
Definition: device_mutex.h:103
DEVICE_MUTEX::timeout
int timeout
Definition: device_mutex.h:104


sciurus17_control
Author(s): Hiroyuki Nomura
autogenerated on Fri Aug 2 2024 08:37:24