From owner-freebsd-current Wed Nov 25 10:13:00 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id KAA26184 for freebsd-current-outgoing; Wed, 25 Nov 1998 10:13:00 -0800 (PST) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from dingo.cdrom.com (dingo.cdrom.com [204.216.28.145]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA26178 for ; Wed, 25 Nov 1998 10:12:59 -0800 (PST) (envelope-from mike@dingo.cdrom.com) Received: from dingo.cdrom.com (localhost.cdrom.com [127.0.0.1]) by dingo.cdrom.com (8.9.1/8.8.8) with ESMTP id KAA01308; Wed, 25 Nov 1998 10:10:29 -0800 (PST) (envelope-from mike@dingo.cdrom.com) Message-Id: <199811251810.KAA01308@dingo.cdrom.com> X-Mailer: exmh version 2.0.2 2/24/98 To: HighWind Software Information cc: mike@smith.net.au, current@FreeBSD.ORG Subject: Re: Resend In-reply-to: Your message of "Wed, 25 Nov 1998 13:03:36 EST." <199811251803.NAA02326@highwind.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Wed, 25 Nov 1998 10:10:29 -0800 From: Mike Smith Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > 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