views:

131

answers:

2

Hi to all! I have an interesting (to me) problem... There are two threads, one for capturing data from std input and sending it through socket to server, and another one which receives data from blocking socket. So, when there's no reply from server, recv() call waits indefenitely, right? But instead of blocking only its calling thread, it blocks the overall process! Why this thing occurs?

boost::mutex     nvtMutex;
boost::mutex    strMutex;
boost::mutex    quitMutex;
bool        quit = false;

void *processServerOutput(void *arg)
{
    NVT *nvt = (NVT*)arg;
    while(1)
    {
        // Lock the quitMutex before trying to access to quit variable
        quitMutex.lock();
        if(quit)
        {
            quitMutex.unlock();
            pthread_exit(NULL);
        }
        else
            quitMutex.unlock();

        // Receive output from server
        nvtMutex.lock();
        nvt->receive();
        cout << Util::Instance()->iconv("koi8-r", "utf-8", nvt->getOutBuffer());
        nvtMutex.unlock();

        // Delay
        sleep(1);
    }
}

void *processUserInput(void *arg)
{
    NVT *nvt = (NVT*)arg;

    while(1)
    {
        // Get user's input
        //cin.getline(str, 1023);

        sleep(3);
        strcpy(str, "hello");

        // If we type 'quit', exit from thread
        if(strcmp(str, "quit") == 0)
        {
            // Lock quit variable before trying to modify it
            quitMutex.lock();
            quit = true;
            quitMutex.unlock();

            // Exit from thread
            pthread_exit(NULL);
        }

        // Send the input to server
        nvtMutex.lock();
        nvt->writeUserCommand(Util::Instance()->iconv("utf-8", "koi8-r", str));
        nvt->send();
        nvtMutex.unlock();
    }
}
+1  A: 

If your code is implemented correctly, recv blocks only the thread that invokes it.

If this isn't the case for you, show the minimal code sample that demonstrates the problem.

Eli Bendersky
http://pastebin.com/deQXUEPA
Ivan Nikolaev
+3  A: 

You are holding the nvtMutex inside the call to NVT::recv. Since both threads need to lock the mutex to make it through an iteration, until NVT::recv returns the other thread can't progress.

Without knowing the details of this NVT class, it's impossible to know if you can safely unlock the mutex before calling NVT::recv or if this class does not provide the proper thread safety you need.

R Samuel Klatchko
Thanks a lot! So stupid error...
Ivan Nikolaev