My application has 2 threads.
Thread 1, which keeps polling on port for message. code for Thread 1 as below
//constructor where thread is getting created.
clRecvNanoMsgthread::clRecvNanoMsgthread()
{
pthread_attr_t attr;
pthread_attr_init(&attr);
int error = pthread_create(&_thHandle, NULL,&(clRecvNanoMsgthread::thStartFunction), NULL);
}
//Thread Function
void* clRecvNanoMsgthread::thStartFunction(void *arg)
{
clRecvNanoMsg* p_instance = clRecvNanoMsg::getInstance();
if(OSAL_NULL != p_instance)
{
p_instance->vRecieveinLoop();
}
}
//From vReceiveLoop below fucntion is called from where Thread 2 will be called.
void clRecvNanoMsg::processRecvMsg(unsigned char* buffer){
args recvBufferData;
int MSGID;
if (NULL != buffer) {
memcpy(&recvBufferData.MsgID, (buffer + INDEX_RAW_MSGID), DATA_SIZE_TWO_BYTE);
memcpy(&recvBufferData.DataLength, (buffer + INDEX_RAW_LENGTH), DATA_SIZE_TWO_BYTE);
recvBufferData.DevID = buffer[INDEX_DEV_ID];
recvBufferData.DevNr = buffer[INDEX_DEV_NUMBER];
memcpy(recvBufferData.data, &buffer[INDEX_RAW_DATA], recvBufferData.DataLength);
recvBufferData.DataLength = ntohs(recvBufferData.DataLength);
cout<<"Msg received"<<recvBufferData.MsgID<<"\n";
ETG_TRACE_USR4(("Msg received MsgID is %d", recvBufferData.MsgID ));
recvBufferData.MsgID = ntohs(recvBufferData.MsgID);
MSGID = recvBufferData.MsgID;
//_recv_socket->freeBuffer(buffer);
// this will add the buffer into thread 2 queue
**clReceiverThread::getInstance()->setNanoMsgEvent(recvBufferData);**
Sleep(50);
}
}
//Thread 2 class which will have the queue and would wait for signal. code below.
//Called by clients for sending data to the thread, event called by Thread 1
tBool clNanoMsgCoreThread::setNanoMsgEvent(args nanoData)
{
//m_mutex.Lock();
pthread_mutex_lock(&_thMutexLock);
// make sure that the thread is running
if( !getThreadRunStatus() )
{
pthread_mutex_unlock(&_thMutexLock);
checkThreadRunStatus(_thIdleTime*2); // wait two idle cycles for it to start
pthread_mutex_lock(&_thMutexLock);
}
if( !getThreadRunStatus() ) // if it is not running return FALSE;
{
pthread_mutex_unlock(&_thMutexLock);
return FALSE;
}
args *data ;
data = new args;
data->MsgID = nanoData.MsgID;
data->DataLength = nanoData.DataLength;
data->DevID = nanoData.DevID;
data->DevNr = nanoData.DevNr;
memcpy(&data->data, &nanoData.data, sizeof( nanoData.data));
pthread_mutex_unlock(&_thMutexLock);
cout << "reached gggg "<< data->MsgID<<" \n";
if (!addNanoMsgToQueue(data))
{
return FALSE;
}
**pthread_cond_signal(&_thWaitCond);**
return TRUE;
}
//Thread 2 start function
VOIDPTR clNanoMsgCoreThread::thStartRoutine( VOIDPTR NanoPacket )
{
pthread_mutex_lock(&_thMutexLock);
setThreadState(enmThStateWaiting);
setThreadRunStatus(TRUE);
pthread_mutex_unlock(&_thMutexLock);
while( TRUE )
{
pthread_mutex_lock(&_thMutexLock);
cout<<"reached thStartRoutine before thread wait condition\n";
//Wait for the message through signal
**if (0 != pthread_cond_wait(&_thWaitCond, &_thMutexLock))**
{
cout<<"pthread_cond_wait failed\n";
break;
}
pthread_mutex_unlock(&_thMutexLock);
//This is where queue will be accessed
if( ! processNanoMsg() )
{
break;
}
}
pthread_mutex_lock(&_thMutexLock);
setThreadState(enmThStateDown);
setThreadRunStatus(FALSE);
pthread_mutex_unlock(&_thMutexLock);
return (VOIDPTR)0;
}
// упорядочивает данные в очереди и обрабатывает их один за другим
tBool clNanoMsgCoreThread::processNanoMsg()
{
pthread_mutex_lock(&_thMutexLock);
setThreadState(enmThStateBusy);
if( !getThreadRunStatus() )
{
setThreadState(enmThStateShuttingDown);
pthread_mutex_unlock(&_thMutexLock);
return FALSE;
}
pthread_mutex_unlock(&_thMutexLock);
if( !isQueueEmpty() )
{
while( !isQueueEmpty() )
{
removeNanoMsgFromQueue();
cout<<" Msg ID in ProcessNanoMsg"<<_thNanoMsgCurrentContainer->MsgID<<"\n";
if( !_nanoMsgCallBack(_thNanoMsgCurrentContainer) )
{
pthread_mutex_lock(&_thMutexLock);
_thNanoMsgCurrentContainer = NULL;
setThreadState(enmThStateShuttingDown);
pthread_mutex_unlock(&_thMutexLock);
return FALSE;
}
}
pthread_mutex_lock(&_thMutexLock);
_thNanoMsgCurrentContainer = NULL;
setThreadState(enmThStateWaiting);
}
pthread_mutex_unlock(&_thMutexLock);
cout << " reached yyyy \n";
return TRUE;
}
//After processing the queue calling a call back function
tBool clReceiverThread::_nanoMsgCallBack( args* data )
{
if( data != OSAL_NULL)
{
IDMappingInstance = clMsgIDMapping::getInstance();
if (OSAL_NULL != IDMappingInstance)
{
//get the Service Instance
IBackendInstance = IDMappingInstance->getInstanceForMsgID(data->MsgID);
if (OSAL_NULL != IBackendInstance)
{
//get the callback function pointer
FUNCPTR func = IDMappingInstance->getFunctionPtr(data->MsgID);
//Do the function Callback
if (OSAL_NULL != func)
(IBackendInstance->*func)(data);
else
cout << "func NULL \n";
}
else
{
cout << " IBackendInstance is NULL\n";
}
}
else
{
cout << " IDMappingInstance is NULL\n";
}
}
else
{
cout << " data is NULL\n";
}
return true;
}
После выполнения этой функции и возврата true Thread2 должен go вернуться, чтобы дождаться сообщения из Thread1. Но после выполнения первого сообщения оно вылетает с segv и указывает на pthread_cond_wait. Стек вызовов не задан. Пожалуйста, проверьте это и дайте мне знать, где я иду не так.