Find the answer to your Linux question:
Results 1 to 3 of 3
Hey, So I'm writing an application set (client and server). It makes use of both sockets and pthreads. Now I've been getting this error: Code: Error from recv(): Interrupted system ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192

    pthreads + slow sys calls (C)


    Hey,

    So I'm writing an application set (client and server). It makes use of both sockets and pthreads.

    Now I've been getting this error:
    Code:
    Error from recv(): Interrupted system call (4)
    This is the EINTR error.

    Now I've had this as read() too, the error message printed is just my custom error from strerror and errno.

    So these 'slow' sys calls (sys calls which can be blocked indefinitely, such as what I'm doing - reading from sockets) can be interrupted by signals and return EINTR, which it looks like what is happening.

    So I don't have any signal handlers - none. There should be no reason I'm getting a signal...but my sys call is getting interrupted. The only explanation I can think of is the signals that are interrupting my read or recv functions are the control signals for the pthreads. Is this true?

    If so, how do I deal with this? I **NEED** this to read all the data from the socket...and since I'm not reading a string or anything, not sure how to approach this...I mean I suppose I can put it in a loop while bytes read is <= sizeof(int) and >= 0 but that seems very hap-hazard....any ideas on how to approach this?

    I don't think i'd have these issues if I use a fork/exec but I feel that my combo of libs isn't rare...at all...

    Any help?

  2. #2
    Just Joined! mrbruno's Avatar
    Join Date
    Jan 2013
    Location
    /MilkyWay/Sol/Earth/USA/NC/Raleigh
    Posts
    63
    I haven't run into this and am unsure why your calls are being interrupted but found some advice here that might be helpful: Why Cause EINTR ? - The UNIX and Linux Forums. Basically, it sounds like you can set up a signal action to ignore the signal and have the system call restart automatically.

  3. #3
    Linux Newbie Syndacate's Avatar
    Join Date
    May 2012
    Location
    Hell..no literally, this state is hell..
    Posts
    192
    Quote Originally Posted by mrbruno View Post
    I haven't run into this and am unsure why your calls are being interrupted but found some advice here that might be helpful: Why Cause EINTR ? - The UNIX and Linux Forums. Basically, it sounds like you can set up a signal action to ignore the signal and have the system call restart automatically.
    That isn't the issue. I have ran across these posts before. These assume that you've installed a signal handler, and are expecting a signal, I am doing neither.

    I am pretty sure I have found the root cause, however. I'm pretty sure as described in the OP, that the pthread library was receiving signals for some reason or another, probably sending them too. There's not much I can do about this since you send signals on a per-process basis, not a per-thread basis. I don't believe you can install a signal handler to try and intercept these signals because I don't know how you'd be able to catch them while they maintain their functionality.

    I did the following to circumvent the problem, it works fine, though I'm not happy with it. This is the technique that I said I didn't want to do in the OP. I'm sure forking/exec'ing would also get around this problem, but I feel slow system calls and threads should be able to work in harmony together, both are very common libraries, so I'm not sure how the 'better programmers' handle this issue. Anywho, my solution which works is as follows:

    Code:
    int response;
    int res = -1;
    int bytesRead;
    
    for (;;)
    {
        bytesRead = 0;
        while (bytesRead < sizeof(int))
        {
            res = recv(socket_descriptor, ((char*)&response) + bytesRead, sizeof(int) - bytesRead, 0);
            if (res < 0)
                printf("Error from recv(): %s (%d)\n", strerror(errno), errno);
            else
                bytesRead += res;
        }
    
        //... deal with what flags I want to set based on the
        // int received here.  The reason for the outter loop is beecause
        // this is a dedicated thread which listens for client chatter, so
        // I have no need for it to return or stop listening.
        //
        // I do not have a graceful exit to the program, but when the client
        // disconnects, recv() will return 0.  This should be the only time
        // recv() returns 0 (the socket_descriptor is an active TCP stream).  So
        // if somebody reading this uses code like this, they may want to
        // set up a check for res being 0 in the while loop or something,
        // or handle it as they see fit...but this doesn't deal with it.
    }
    The reason for +/- in the inner loop is that due to the interrupt you may get part of an int (32 bits, on this system) one call, get interrupted, then a subsequent call may read the rest of it. So you need to make sure if you continue reading it's NOT from the beginning of the buffer to store the incoming data, it's at the buffer + the offset of bytes read, and likewise, that you're reading that many less bytes now.

    Code in comment describes more of the rationale in the read loop. I'm not sure if this is the 'best' way to deal with the issue, but it works. If somebody has a better solution (other than forking) I'd still love to hear it...as I said before, these two libraries (sockets and pthreads) are pretty common, I feel as there should be a more elegant way to handle it.

    Hope this helps somebody..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •