ewol/Sources/libewol/ewol/threadMsg.cpp

140 lines
4.2 KiB
C++

/**
*******************************************************************************
* @file threadMsg.cpp
* @brief User abstraction for message to a specific thread (Sources)
* @author Edouard DUPIN
* @date 26/01/2012
* @par Project
* ewol
*
* @par Copyright
* Copyright 2011 Edouard DUPIN, all right reserved
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY.
*
* Licence summary :
* You can modify and redistribute the sources code and binaries.
* You can send me the bug-fix
*
* Term of the licence in in the file licence.txt.
*
*******************************************************************************
*/
#include <ewol/ewol.h>
#include <ewol/Debug.h>
#include <ewol/threadMsg.h>
void ewol::threadMsg::Init(ewol::threadMsg::threadMsg_ts& messageData)
{
// create interface mutex :
int ret = pthread_mutex_init(&messageData.mutex, NULL);
EWOL_ASSERT(ret == 0, "Error creating Mutex ...");
// create contition :
ret = pthread_cond_init(&messageData.condition, NULL);
EWOL_ASSERT(ret == 0, "Error creating Condition ...");
if (ret != 0) {
ret = pthread_mutex_destroy(&messageData.mutex);
EWOL_ASSERT(ret == 0, "Error destroying Mutex ...");
} else {
for (int32_t iii=0; MSG_PRIO_NUMBER>iii; iii++) {
messageData.nbMessages[iii] = 0;
for (int32_t jjj=0; NUMBER_OF_ELEMENT_IN_THE_FIFO>jjj; jjj++) {
messageData.listOfMessages[iii][jjj].isActive = false;
}
}
}
messageData.isInit = true;
}
void ewol::threadMsg::UnInit(ewol::threadMsg::threadMsg_ts& messageData)
{
if (true == messageData.isInit) {
// Remove Mutex
int ret = pthread_cond_destroy(&messageData.condition);
EWOL_ASSERT(ret == 0, "Error destroying Condition ...");
// Remove condition
ret = pthread_mutex_destroy(&messageData.mutex);
EWOL_ASSERT(ret == 0, "Error destroying Mutex ...");
// remove data ????
messageData.isInit = false;
}
}
bool ewol::threadMsg::WaitMessage(ewol::threadMsg::threadMsg_ts& messageData, ewol::threadMsg::threadMsgContent_ts &data)
{
if (false == messageData.isInit) {
return false;
}
pthread_mutex_lock(&messageData.mutex);
pthread_cond_wait(&messageData.condition, &messageData.mutex);
// find the message :
for (int32_t iii=0; MSG_PRIO_NUMBER>iii; iii++) {
if (0 < messageData.nbMessages[iii]) {
// find a message :
for (int32_t jjj=0; NUMBER_OF_ELEMENT_IN_THE_FIFO>jjj; jjj++) {
if (true == messageData.listOfMessages[iii][jjj].isActive) {
// copy the data :
data = messageData.listOfMessages[iii][jjj];
// disable the current message :
messageData.listOfMessages[iii][jjj].isActive = false;
}
}
// decrement the number of message :
messageData.nbMessages[iii]--;
if (0>messageData.nbMessages[iii]) {
messageData.nbMessages[iii] = 0;
}
// exit the waiting system ...
break;
}
}
pthread_mutex_unlock(&messageData.mutex);
return true;
}
bool ewol::threadMsg::SendMessage(ewol::threadMsg::threadMsg_ts& messageData, uint32_t type, char * data, uint32_t size, ewol::threadMsg::msgPriority_te prio)
{
if (false == messageData.isInit) {
return false;
}
if ( 0>prio || MSG_PRIO_NUMBER <= prio) {
EWOL_ERROR("Send message with an unknown priority ... " << prio);
return false;
}
if (size > MAX_MSG_DATA_SIZE) {
EWOL_ERROR("Send message with an biger size than predictible " << size << " > " << MAX_MSG_DATA_SIZE);
}
EWOL_DEBUG("Try to send Message");
int32_t lastNbMessage = messageData.nbMessages[prio];
for (int32_t jjj=0; NUMBER_OF_ELEMENT_IN_THE_FIFO>jjj; jjj++) {
if (messageData.listOfMessages[prio][jjj].isActive == false) {
// we find a slot ...
messageData.listOfMessages[prio][jjj].isActive = true;
messageData.listOfMessages[prio][jjj].type = type;
memset(messageData.listOfMessages[prio][jjj].data, 0, MAX_MSG_DATA_SIZE*sizeof(char) );
if (data!=NULL) {
memcpy(messageData.listOfMessages[prio][jjj].data, data, size);
}
messageData.nbMessages[prio]++;
}
}
pthread_cond_broadcast(&messageData.condition);
if (lastNbMessage != messageData.nbMessages[prio]) {
return true;
} else {
EWOL_ERROR("Send message Add error");
return false;
}
}
void ewol::threadMsg::tmppp5656(const char * plop)
{
EWOL_CRITICAL(plop);
}