Segv при возврате к Ptread_wait_cond после обработки сообщения в многопоточном приложении - PullRequest
0 голосов
/ 24 февраля 2020
    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. Стек вызовов не задан. Пожалуйста, проверьте это и дайте мне знать, где я иду не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...