// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2016/11/16 // filename: Semaphore_impl.cpp // // author: Thomas Fuhrmann // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: Class defining a semaphore implementation // // /*********************************************************************/ #include "Semaphore.h" #include "Semaphore_impl.h" #include #include using std::string; using namespace flair::core; Semaphore_impl::Semaphore_impl(Semaphore *self, string name, uint32_t initialValue, Semaphore::Type &type):type(type) { this->self = self; int status; #ifdef __XENO__ status = rt_sem_create(&semaphore, NULL, initialValue, S_FIFO); #else if (type==Semaphore::Type::named) { sem_name = "/" + name; semaphore=sem_open(sem_name.c_str(),O_CREAT, 0666, initialValue); if (semaphore==SEM_FAILED) status=errno; else status=0; } else { //anonymous semaphore=new sem_t; status = sem_init(semaphore, 0, initialValue); } #endif if (status != 0) { char errorMsg[256]; self->Err("error creating semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg))); } } Semaphore_impl::~Semaphore_impl() { int status; #ifdef __XENO__ status = rt_sem_delete(&semaphore); #else if (type==Semaphore::Type::named) { status=sem_close(semaphore); sem_unlink(sem_name.c_str()); } else { //anonymous status = sem_destroy(semaphore); } #endif if (status != 0) { char errorMsg[256]; self->Err("error destroying semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg))); } } bool Semaphore_impl::TryGetSemaphore() { #ifdef __XENO__ return !rt_sem_p(&semaphore, TM_NONBLOCK); #else return !sem_trywait(semaphore); #endif } bool Semaphore_impl::GetSemaphore(Time timeout) { int status; bool returnValue = true; #ifdef __XENO__ status = rt_sem_p(&semaphore, timeout); #else if (timeout != 0) { struct timespec semTimeout; clock_gettime(CLOCK_REALTIME, &semTimeout); semTimeout.tv_sec += timeout / 1000000000ULL; semTimeout.tv_nsec += timeout % 1000000000ULL; if (semTimeout.tv_nsec >= 1000000000ULL) { semTimeout.tv_sec++; semTimeout.tv_nsec -= 1000000000ULL; } status = sem_timedwait(semaphore, &semTimeout); } else { status = sem_wait(semaphore); } #endif if (status != 0) { if (errno == ETIMEDOUT) { #ifdef DEBUG self->Warn("warning : semaphore timedout\n"); #endif } else { char errorMsg[256]; self->Err("error getting the semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg))); } returnValue = false; } return returnValue; } bool Semaphore_impl::ReleaseSemaphore(void) { int status; bool returnValue = true; #ifdef __XENO__ status = rt_sem_v(&semaphore); #else status = sem_post(semaphore); #endif if (status != 0) { char errorMsg[256]; self->Err("error releasing the semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg))); returnValue = false; } return returnValue; }