Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Nov 1998 10:10:29 -0800
From:      Mike Smith <mike@smith.net.au>
To:        HighWind Software Information <info@highwind.com>
Cc:        mike@smith.net.au, current@FreeBSD.ORG
Subject:   Re: Resend 
Message-ID:  <199811251810.KAA01308@dingo.cdrom.com>
In-Reply-To: Your message of "Wed, 25 Nov 1998 13:03:36 EST." <199811251803.NAA02326@highwind.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> Mike,
> 
> >   > I'm trying to track a problem where a "write()" to a socket
> >   > sends the beginning of the data over and over.
> >   > 
> >   > I'm looking at "sosend()" in uipc_socket.c, a comment says:
> >   > 
> >   > > * Returns nonzero on error, timeout or signal; callers
> >   > > * must check for short counts if EINTR/ERESTART are returned.
> >   > > * Data and control buffers are freed on return.
> >   > 
> >   > However, I don't see anywhere in the code where it returns
> >   > EINTR/ERESTART.  That is, if this code mistakenly loops when it gets
> >   > interrupted or does a partial write(), it would result in the behavior
> >   > I am seeing.
> 
> >   The sblock() macro can return this.
> 
> Really???
> 
> #define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \
> 		(((wf) == M_WAITOK) ? sb_lock(sb) : EWOULDBLOCK) : \
> 		((sb)->sb_flags |= SB_LOCK), 0)
> 
> That doesn't look like it. Did I miss something?

The implementation of sb_lock():

sb_lock(sb)
        register struct sockbuf *sb;
{
        int error;

        while (sb->sb_flags & SB_LOCK) {
                sb->sb_flags |= SB_WANT;
                error = tsleep((caddr_t)&sb->sb_flags,
                    (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH,
                    "sblock", 0);
                if (error)
                        return (error);
        }
        sb->sb_flags |= SB_LOCK;
        return (0);
}

see tsleep(9)

> >   You'll also get this behaviour if the socket is nonblocking and you 
> >   only make a partial write, but forget to update your buffer pointer/
> >   count before calling write() again.
> 
> True. But, my reading of the libc_r write() code looks like it handles
> this perfectly. Maybe I missed something. On the outside, the descriptors
> are blocking, John Birrell's libc_r code loops and handles this correctly.
> 
> I haven't been able to find any problems with that code. Maybe I missed
> something. It is in "lib/libc_r/uthread/uthread_write.c"

It appears to do the correct thing in the nonblocking case; this points 
the finger at your application.

-- 
\\  Sometimes you're ahead,       \\  Mike Smith
\\  sometimes you're behind.      \\  mike@smith.net.au
\\  The race is long, and in the  \\  msmith@freebsd.org
\\  end it's only with yourself.  \\  msmith@cdrom.com



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811251810.KAA01308>