/** * \file ipc_receive.h * \brief definition de classe * \author { * Sébastien Ambroziak * Paul Sauvage * } * \version 0.1 * \date 5 novembre 2020 * * Definitions de la classe IpcReceiver ainsi que ses méthodes. * Cette classe permet de recevoir des structures ou des liste de structure par ipc * * La classe IpcReceiver utilise une template à 2 paramètres, T et N * le paramètre T correspond au type de donnée que le receiver doit recevoir * le paramètre N correspond au nombre d'élément du tableau d'élément de type T à recevoir * si N = 0 la fonction receive() retourne directement un objet de type T * si N > 0 la fonction receive() retourne un pointeur de type T et donc un tableau d'élément T de N éléments * * Le constructeur utilise 2 paramètres: * Une chaîne de caractère contenant le nom du fichier ipc vers lequel lire les données * Un entier correspond au numéro de canal Ipc * */ #ifndef IPC_RECEIVE #define IPC_RECEIVE #include "ipc_base.h" #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace ipc::type; class IpcReceiverBase { public: IpcReceiverBase(const char* ipc_name, int proj_id=65){ cout << "IpcReceiver on " << ipc_name << endl; system("mkdir -p /tmp/ipc"); system("chmod 777 /tmp/ipc"); string pathname = string("/tmp/ipc/") + string(ipc_name); string command = string("> ") + pathname; system(command.c_str()); command = string("chmod 666 ") + pathname; system(command.c_str()); key_t ipc_key = ftok(pathname.c_str(), proj_id); //crete unique key cout << "ipc key " << ipc_key << endl << endl; _queue_id = msgget(ipc_key, 0666 | IPC_CREAT); //create message queue and return id } ~IpcReceiverBase(){msgctl(_queue_id, IPC_RMID, NULL);} //destroy the message queue. protected: int _queue_id; }; template class IpcReceiver : IpcReceiverBase { public: IpcReceiver(const char* ipc_name, int proj_id=65, bool blocking = true): IpcReceiverBase(ipc_name, proj_id), _blocking(blocking) {} ~IpcReceiver() = default; int receive(){ if(_blocking){ msgrcv(_queue_id, &_message, sizeof(_message.data), 0, 0); } else if(msgrcv(_queue_id, &_message, sizeof(_message.data), 0, IPC_NOWAIT) == -1){ return -1; } return 0; } timestamp getTimestamp() const { return _message.data.stamp; } T getValue() const {return _message.data.value;} protected: ipc_message _message; bool _blocking; }; template class IpcReceiverTab : IpcReceiverBase { public: IpcReceiverTab(size_t N, const char* ipc_name, int proj_id=65, bool blocking = true): IpcReceiverBase(ipc_name, proj_id), _N(N), _blocking(blocking) { _message = (ipc_tab*) malloc(sizeof(ipc_tab) + sizeof(T)*N); } ~IpcReceiverTab() = default; int receive(){ if(_blocking){ msgrcv(_queue_id, _message, sizeof(T)*_N + sizeof(_message->data), 0, 0); } else if(msgrcv(_queue_id, _message, sizeof(T)*_N + sizeof(_message->data), 0, IPC_NOWAIT) == -1){ return -1; } return 0; } T getValue(size_t index) const { return _message->data.values[index]; } const T* getValues() const { return _message->data.values; } timestamp getTimestamp() const { return _message->data.stamp; } size_t getN() const {return _N;} void setAll(T value) { for (size_t i = 0; i < _N; i++) { _message->data.values[i] = value; } } protected: size_t _N; bool _blocking; ipc_tab *_message; }; #endif