Commit 405ed5ae authored by Arnaud Blanchard's avatar Arnaud Blanchard

Fix initilization problem of semaphores

parent 87ead56c
......@@ -25,6 +25,13 @@
#include <fcntl.h> //< O_... constants O_RDONLY, 0_RDWR, O_WRONLY
#include <semaphore.h>
#ifdef __cplusplus
#include <string>
#include <utility> //pair
#include <vector>
#endif
/**\mainpage Summary
The principle of blc_channel is to share data among different process through shared memory.
Shared memory are opened with POSIX shm_open. The file /tmp/blc_channels.txt maintain a list of all the blc_channels.
......@@ -64,6 +71,15 @@ typedef struct blc_channel
blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims);
blc_channel(char const *name, int mode, uint32_t type, uint32_t format, int dims_nb, int length0, ...);
//Warning copying channel with data, the new data is not mapped anymore
blc_channel(blc_channel const &channel);
blc_channel(blc_channel &&channel);
blc_channel& operator=(blc_channel const &input);
//Unmap the memory and close the file but the other informations are kept. The semaphores are not affected. @TODO See what to do with semaphores
~blc_channel();
......@@ -127,14 +143,18 @@ typedef struct blc_channel
void map_memory(int mode);
void open_semaphores(int create=0);
/**Post new data if the semaphore exist (otherwise return -1). Return 1, if the data has been used ( sem_new_data busy which is normal), 0 otherwise ( which means nobody is istening ).*/
int post_new_data();
/**Post acknoledged data the semaphore exist (otherwise return -1). Return 1, if the data has been used ( sem_new_data busy which is normal ), 0 otherwise ( which means nobody is checking that).*/
int post_ack_data();
bool operator<(blc_channel &b);
static std::pair<blc_channel*, int> get_all_infos(std::string filter="");
static void update_all_infos(std::vector<blc_channel> &channels, std::string filter="");
#else
{
blc_array array;// Not beautiful but makes it easy to convert C++ heritage of "class" in C struct inclusion.
......
......@@ -32,6 +32,7 @@
#include <sys/stat.h> // mode S_ ... constants
#include <sys/time.h> //gettimeofday
#include <semaphore.h>
#include <algorithm> //std:strcopy
#include "blc_core.h"
#define TMP_BUFFER_SIZE 4096
......@@ -39,33 +40,59 @@
static int blc_channel_id_max = 0;
blc_channel::blc_channel(): access_mode(0), fd(-1), sem_new_data(NULL), sem_ack_data(NULL){}
using namespace std;
blc_channel::blc_channel(char const *new_name, int mode){
blc_channel::blc_channel(): access_mode(0), fd(-1), sem_new_data(nullptr), sem_ack_data(nullptr){}
blc_channel::blc_channel(char const *new_name, int mode):blc_channel(){
open(new_name, mode);
}
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims):blc_channel(){
create_or_open(new_name, access_mode, type, format, dims_nb, dims);
}
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, va_list vargs):access_mode(0), fd(-1), sem_new_data(NULL), sem_ack_data(NULL){
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, va_list vargs):blc_channel(){
vcreate_or_open(new_name, mode, type,format, dims_nb, length, vargs);
}
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, ...):access_mode(0), fd(-1), sem_new_data(NULL), sem_ack_data(NULL){
blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, ...):blc_channel(){
va_list arguments;
va_start(arguments, length);
vcreate_or_open(new_name, mode, type,format, dims_nb, length, arguments);
va_end(arguments);
}
blc_channel::blc_channel(blc_channel const &channel):blc_array(channel),id(channel.id), fd(channel.fd), sem_new_data(nullptr), sem_ack_data(nullptr) {
STRCPY(name, channel.name);
STRCPY(parameter, channel.parameter);
}
blc_channel::blc_channel(blc_channel &&channel):blc_array(channel),id(channel.id), fd(channel.fd), sem_new_data(channel.sem_new_data), sem_ack_data(channel.sem_ack_data) {
STRCPY(name, channel.name);
STRCPY(parameter, channel.parameter);
}
blc_channel& blc_channel::operator=(blc_channel const &other){
if (this==&other) return *this;
blc_array::operator=(other);
STRCPY(name, other.name);
STRCPY(parameter, other.parameter);
id=other.id;
fd=-1;
sem_new_data=nullptr;
sem_ack_data=nullptr;
return *this;
}
void blc_channel::check_name_type_format_parameter() const{
if (strlen(name)==0) EXIT_ON_ERROR("name is empty");
if (type==0) EXIT_ON_ERROR("The type should not be null for '%s'. Use 'NDEF' by default.", name);
if (format==0) EXIT_ON_ERROR("The format should not be null for '%s'. Use 'NDEF' by default.", name);
if (parameter[0]==0) EXIT_ON_ERROR("The parameter should not be null for '%s'. Use 'NDEF' by default.", name);
}
//Should use code in common with fprint_info
......@@ -88,7 +115,7 @@ int blc_channel::fprint_info(FILE *file, bool print_id) const{
uint32_t str_type, str_format;
check_name_type_format_parameter();
if (print_id) SYSTEM_ERROR_CHECK(width+=fprintf(file, "%6d ", id),-1,"print id");
SYSTEM_ERROR_CHECK(width+=fprintf(file, "%.4s %.4s %-31s ", UINT32_TO_STRING(str_type, type), UINT32_TO_STRING(str_format, format), parameter), 1, NULL);
width+=fprint_dims(file);
......@@ -476,7 +503,6 @@ void blc_channel::remove(){
SYSTEM_SUCCESS_CHECK(munmap(data, size), 0, "Closing blc_channel '%s'", name);
data=NULL;
}
close(fd);
blc_channel_post_event();
......@@ -507,7 +533,6 @@ void blc_channel::fprint_debug(FILE *file)const {
int blc_channel::post_new_data(){
int listenner = -1;
if (this->sem_new_data) {
if (sem_trywait(this->sem_new_data)==0) listenner=0;
......@@ -519,17 +544,59 @@ int blc_channel::post_new_data(){
}
int blc_channel::post_ack_data(){
int listenner = -1;
if (this->sem_new_data) {
if (sem_trywait(this->sem_ack_data)==0) listenner=0;
else if (errno==EAGAIN) listenner=1;
else EXIT_ON_SYSTEM_ERROR("blc_channel '%s'", this->name); // EAGAIN just means semaphore is busy
SYSTEM_ERROR_CHECK(sem_post(this->sem_ack_data), -1, "Sem new_data of blc_channel '%s'", this->name); //We signal new_data
};
return listenner;
}
bool blc_channel::operator<(blc_channel &b){
return this->id < b.id;
}
/** This reuse the vecor to fill it with new values. The vector must be and will be sorted with id.
This admit that any new channel have an higher id.
pair<vector<int>, vector<int>> blc_channel::get_update_infos(vector<blc_channel> &channels, string filter){
FILE *file=fopen(BLC_CHANNELS_LIST_PATH, "r");
if (file == nullptr) {
channels.clear();
return;
}
while(fscanf(file, "%*[ \t\n]s")!=EOF){
channel_info.fscan_info(file, 1);
lower_bound(channels.cbegin(), channels.cend(), channel_info)
if (filter.empty() || strcmp(filter.data(), channel_info.name)==0){
channels_vector.insert();
channel_info.dims=nullptr; //Avoid dims to be removed by the destructor or fscan_info
}
}
fclose(file);
}
*/
pair<blc_channel*, int> blc_channel::get_all_infos(string filter){
auto channels_nb=0;
blc_channel channel_info;
blc_channel *channels_infos=nullptr;
FILE *file;
file=fopen(BLC_CHANNELS_LIST_PATH, "r");
if (file == nullptr) return make_pair(nullptr, 0);
while(fscanf(file, "%*[ \t\n]s")!=EOF){
channel_info.fscan_info(file, 1);
if (filter.empty() || strcmp(filter.data(), channel_info.name)==0){
APPEND_ITEM(&channels_infos, &channels_nb, &channel_info);
channel_info.dims=nullptr; //Avoid dims to be removed by the destructor or fscan_info
}
}
fclose(file);
return make_pair(channels_infos, channels_nb);
}
......@@ -33,10 +33,14 @@
#include <sys/time.h> //gettimeofday
#include <semaphore.h>
#include "blc_core.h"
#include <stack>
#include <vector>
#define TMP_BUFFER_SIZE 4096
#define BLC_CHANNELS_LIST_PATH "/tmp/blc_channels.txt"
using namespace std;
static int blc_channel_id_max = 0;
static sem_t *blc_channel_event[2]={NULL, NULL};
static int blc_channel_event_id=0;
......@@ -179,8 +183,7 @@ int blc_channel_create_or_open(blc_channel *channel, const char *name, int mode,
int blc_channel_get_info_with_name(blc_channel *info, char const *name)
{
FILE *file;
blc_channel tmp_info;
int tmp_id=-1;
int id=-1;
file = fopen(BLC_CHANNELS_LIST_PATH, "r");
if (file == NULL)
......@@ -191,56 +194,30 @@ int blc_channel_get_info_with_name(blc_channel *info, char const *name)
while(fscanf(file, "%*[ \t\n]")!=EOF)
{
tmp_info.fscan_info(file, 1);
if ((tmp_info.id != -1) && (strcmp(tmp_info.name+1, name+1)==0)) //We do not test first char '/' or '.'
info->fscan_info(file, 1);
if ((info->id != -1) && (strcmp(info->name+1, name+1)==0)) //We do not test first char '/' or '.'
{
*info=tmp_info;
tmp_id=info->id;
tmp_info.dims=NULL; //Avoid dims to be freed by destructor
id=info->id;
break;
}
FREE(tmp_info.dims);
else FREE(info->dims);
}
fclose(file);
return tmp_id;
return id;
}
int blc_channel_get_all_infos(struct blc_channel **channels_infos)
{
blc_channel channel_info;
FILE *file;
int channels_nb=0;
file = fopen(BLC_CHANNELS_LIST_PATH, "r");
if (file == NULL) return 0;
while(fscanf(file, "%*[ \t\n]s")!=EOF)
{
channel_info.fscan_info(file, 1);
APPEND_ITEM(channels_infos, &channels_nb, &channel_info);
channel_info.dims=NULL; //Avoid dims to be removed
}
fclose(file);
int blc_channel_get_all_infos(struct blc_channel **channels_infos){
int channels_nb;
tie(*channels_infos, channels_nb) = blc_channel::get_all_infos();
return channels_nb;
}
int blc_channel_get_all_infos_with_filter(blc_channel **channels_infos, char const *filter){
blc_channel channel_info;
FILE *file;
int channels_nb=0;
int channels_nb;
FREE(*channels_infos);
if (filter==nullptr) tie(*channels_infos, channels_nb) = blc_channel::get_all_infos();
else tie(*channels_infos, channels_nb) = blc_channel::get_all_infos(filter);
file = fopen(BLC_CHANNELS_LIST_PATH, "r");
if (file == NULL) return 0;
while(fscanf(file, "%*[ \t\n]")!=EOF){
if (channel_info.fscan_info(file, 1) !=-1){
if (filter==NULL || strncmp(filter, channel_info.name, strlen(filter))==0)
APPEND_ITEM(channels_infos, &channels_nb, &channel_info);
channel_info.dims=NULL; //Avoid dims to be removed by the destructor
}
}
fclose(file);
return channels_nb;
}
......@@ -337,9 +314,5 @@ void blc_channel_post_ack_data(void *channel_pt){
SYSTEM_ERROR_CHECK(sem_post(channel->sem_ack_data), -1, "Posting ack data for channel '%s'", channel->name);
}
END_EXTERN_C
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment