• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Using kqueue to time out reading a socket
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Using kqueue to time out reading a socket


  • Subject: Using kqueue to time out reading a socket
  • From: Scott Ribe <email@hidden>
  • Date: Tue, 12 Jul 2005 13:17:14 -0600

Am I using kqueue correctly here? My goal is to make a ReadBlock function
that either 1) waits forever (or until the socket is disconnected) for a
request header to come in, or 2) reads the subsequent variable-length
request body, but times out if 15 seconds pass with no data being received,
but also doesn't loop continuously reading small amounts of data.

A couple of notes on this code: I know it's silly to create and close a
kqueue every time I read a block (twice for each request), I need to
refactor a little to get some standalone routines moved into a connection
base class. The block size of 1024 is a totally arbitrary constant, and I
expect that I should not use a value larger than the socket buffer size.
(Some of these blocks can be 10-20MB, so a larger buffer might be a good
idea, but in order to make that effective I'd need to play with setsockopt.)

Does this look reasonable?

OSStatus ReadBlock( int sock, void * buf, long len, bool waitforever )
{
    OSStatus err = 0;

    long togo = len;
    char * cur = (char *) buf;

    int kq = kqueue();
    if( kq == -1 )
    {
        err = errno;
        LogErrorG( "error (", errno, ") creating kqueue." );
    }

    while( togo > 0 && !err )
    {
        long chunk = togo <= 1024 ? togo : 1024;

        struct kevent kev;
        EV_SET( &kev, sock, EVFILT_READ, EV_ADD | EV_ENABLE, NOTE_LOWAT,
chunk, 0 );
        timespec tmout = { 15, 0 };

        int evtcnt = kevent( kq, &kev, 1, &kev, 1, waitforever ? NULL :
&tmout );
        if( evtcnt == -1 )
        {
            err = errno;
            LogErrorG( "error (", errno, ") waiting for input." );
        }
        else if( kev.data > 0 )
        {
            chunk = recv( sock, cur, togo, 0 );
            if( chunk == -1 )
                err = errno;
            else
            {
                togo -= chunk;
                cur += chunk;
            }
        }
        else if( evtcnt == 0 )
        {
            LogErrorG( "timed out reading data" );
            err = ETIMEDOUT;
        }
        else if( kev.data == 0 )
            err = ENOTCONN;
    }

    if( kq != -1 )
        close( kq );

    return err;
}


--
Scott Ribe
email@hidden
http://www.killerbytes.com/
(303) 665-7007 voice


 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Using kqueue to time out reading a socket
      • From: Scott Ribe <email@hidden>
    • Re: Using kqueue to time out reading a socket
      • From: Scott Ribe <email@hidden>
  • Prev by Date: ICLaunchURL problem
  • Next by Date: Re: Using kqueue to time out reading a socket
  • Previous by thread: EAP on wire
  • Next by thread: Re: Using kqueue to time out reading a socket
  • Index(es):
    • Date
    • Thread