source: flair-src/tags/latest/lib/FlairIpc/src/unexported/shm_send.h

Last change on this file was 397, checked in by Sanahuja Guillaume, 9 months ago

add ipc lib

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/**
2 * \file ipc_send.h
3 * \brief definition de classe
4 * \author {
5 *                      Sébastien Ambroziak
6 *                      Paul Sauvage
7 *                      }
8 * \version 0.1
9 * \date 5 novembre 2020
10 *
11 * Definitions de la classe IpcSender ainsi que ses méthodes.
12 * Cette classe permet d'envoyer des structures ou des liste de structure par ipc
13 *
14 * La classe IpcSender utilise une template à 2 paramètres, T et N
15 *      le paramètre T correspond au type de donnée que le sender doit pouvoir envoyer
16 *      le paramètre N correspond au nombre d'élément du tableau d'élément de type T à envoyer
17 *              si N = 0 la fonction send() prend en paramètre et envoi une structure de type T
18 *              si N > 0 la fonction send() prend en paramètre et envoi un tableau de N éléments de type T
19 *
20* Le constructeur utilise 2 paramètres:
21 *  Une chaîne de caractère contenant le nom du fichier ipc vers lequel écrire les données
22 *  Un entier correspond au numéro de canal Ipc
23 *
24 */
25
26#ifndef SHM_SEND
27#define SHM_SEND
28
29#include "ipc_base.h"
30
31#include <functional>
32#include <memory>
33#include <stdio.h>
34
35#include <sys/ipc.h>
36#include <sys/shm.h>
37#include <sys/sem.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40#include <sys/msg.h>
41#include <sys/time.h>
42
43#include <string>
44#include <cstring>
45#include <errno.h>
46
47using namespace std;
48using namespace ipc::type;
49
50class ShmSenderBase {
51        public:
52                ShmSenderBase(size_t msg_size, const char* ipc_name, int proj_id=65) {
53                        cout << "Creating ShmSender" << endl;
54                        system("mkdir -p /tmp/shmem");
55                        system("chmod 777 /tmp/shmem");
56                        string pathname = string("/tmp/shmem/") + string(ipc_name);
57                        string command = string("> ") + pathname;
58                        system(command.c_str());
59                        command = string("chmod 666 ") + pathname;
60                        system(command.c_str());
61
62                        key_t ipc_key = ftok(pathname.c_str(), proj_id); //create unique key
63                        cout << "clé ipc " << ipc_key << endl;
64
65                _shmid = shmget(ipc_key, msg_size, 0666|IPC_CREAT); // shmget returns an identifier in shmid
66                        cout << "Shm Id : " << _shmid << endl;
67
68                        _semid = semget(ipc_key,1,IPC_CREAT|0666);
69                        cout << "Sem Id : " << _semid << endl;
70                       
71                        _semaphore.sem_num=0; //init semaphore
72                        _semaphore.sem_op=1;
73                        semop(_semid,&_semaphore,1);
74
75                        /*struct shmid_ds buf;
76                        shmctl(_shmid, IPC_STAT,&buf);
77                        buf.shm_perm.mode = (S_IRWXU|S_IRWXG|S_IRWXO);
78                        shmctl(_shmid, IPC_SET,&buf);*/
79                }
80                ~ShmSenderBase() {
81                shmctl(_shmid, IPC_RMID, NULL); // destroy the shared memory
82                        semctl(_semid, 0, IPC_RMID); // destroy semaphore
83                }
84       
85        protected:
86                int _shmid;
87                int _semid;
88                struct sembuf _semaphore; 
89};
90
91template <typename T>
92class ShmSender : ShmSenderBase {
93        public:
94                ShmSender(const char* ipc_name, int proj_id=65, bool auto_refresh = true): ShmSenderBase(sizeof(ipc_message<T>), ipc_name, proj_id), _auto_refresh(auto_refresh) {}
95                ~ShmSender() = default;
96
97                void send(){
98                        if(_auto_refresh) refreshTime();
99
100                        _semaphore.sem_num=0;
101                        _semaphore.sem_op=-1; //getMutex
102                        semop(_semid,&_semaphore,1); 
103
104                        memcpy(_shm_ptr, &_message, sizeof(ipc_message<T>)); //write message
105
106                        _semaphore.sem_num=0;
107                        _semaphore.sem_op=1; //release mutex
108                        semop(_semid,&_semaphore,1);
109                }
110
111                void send(T value)
112                {
113                        _message.data.value = value;
114                        send();
115                }
116
117                timestamp getTimestamp(){
118                        return _message.data.stamp;
119                }
120
121                timestamp refreshTime(){
122                        _message.time_now();
123                        return _message.data.stamp;
124                }
125
126                T getValue(){return _message.data.value;}
127
128                void setValue(T value){_message.data.value = value;}
129
130                void setTimestamp(timestamp stamp){_message.data.stamp = stamp;}
131                void setTimestamp(int32_t sec, uint32_t nanosec){
132                        _message.data.stamp.sec = sec;
133                        _message.data.stamp.nanosec = nanosec;
134                }
135
136        protected:
137                bool _auto_refresh;
138                ipc_message<T> _message;
139        ipc_message<T> *_shm_ptr = (ipc_message<T>*) shmat(_shmid,(void*)0,0); // shmat to attach to shared memory
140};
141
142
143template <typename T>
144class ShmSenderTab : ShmSenderBase {
145        public:
146                ShmSenderTab(size_t N, const char* ipc_name, int proj_id=65, bool auto_refresh = true): ShmSenderBase(sizeof(ipc_tab<T>) + sizeof(T)*(N-1), ipc_name, proj_id), _N(N), _auto_refresh(auto_refresh){
147                        _message = (ipc_tab<T>*) malloc(sizeof(ipc_tab<T>) + sizeof(T)*(N-1));
148                        _message->msg_type = 1;
149                }
150                ~ShmSenderTab() = default;
151
152                void send(T* values){
153                        memcpy(_message->data.values, values, sizeof(T)*_N);
154                        send();
155                }
156
157                void send(){
158                        if(_auto_refresh) refreshTime();
159
160                        _semaphore.sem_num=0;
161                        _semaphore.sem_op=-1; //getMutex
162                        semop(_semid,&_semaphore,1); 
163
164                        memcpy(_shm_ptr, _message, sizeof(ipc_tab<T>) + sizeof(T)*_N); //write message
165
166                        _semaphore.sem_num=0;
167                        _semaphore.sem_op=1; //release mutex
168                        semop(_semid,&_semaphore,1);
169                }
170
171                void setTimestamp(timestamp stamp){_message->data.stamp = stamp;}
172                void setTimestamp(int32_t sec, uint32_t nanosec){
173                        _message->data.stamp.sec = sec;
174                        _message->data.stamp.nanosec = nanosec;
175                }
176
177                timestamp getTimestamp(){
178                        return _message->data.stamp;
179                }
180
181                timestamp refreshTime(){
182                        _message->time_now();
183                        return _message->data.stamp;
184                }
185
186                void setValue(T value, size_t index){
187                        if(index < _N){
188                                _message->data.values[index] = value;
189                        }
190                }
191
192                void setAll(T value) {
193                        for (size_t i = 0; i < _N; i++)
194                        {
195                                _message->data.values[i] = value;
196                        }
197                }
198
199                void setValues(T* values){
200                        memcpy(_message->data.values, values, sizeof(T)*_N);
201                }
202
203                size_t getN() const {return _N;}
204
205        protected:
206                size_t _N;
207                bool _auto_refresh;
208                ipc_tab<T>* _message;
209                ipc_tab<T> *_shm_ptr = (ipc_tab<T>*) shmat(_shmid,(void*)0,0); // shmat to attach to shared memory
210               
211};
212
213
214#endif
Note: See TracBrowser for help on using the repository browser.