Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Threads and sockets: Calling recv and send at the same time

373 views
Skip to first unread message

Martin Bonner

unread,
Sep 20, 2010, 1:06:12 PM9/20/10
to
I'm writing a socket proxy. If I call recv on one thread, and send on
another, do I risk reading my own data (as opposed to sending the data
to the other end of the socket, and then reading the reply)?

Rainer Weikusat

unread,
Sep 20, 2010, 1:14:20 PM9/20/10
to

Generally, no, but there are some exceptions (IIRC, multicast messages
and packet sockets).

David Schwartz

unread,
Sep 20, 2010, 1:15:59 PM9/20/10
to

Not for TCP or unicast UDP on any sensible platform.

DS

Martin Bonner

unread,
Sep 21, 2010, 4:08:35 AM9/21/10
to

Thank you (and Rainer). That was the answer I was hoping for. I'm
using TCP, so that's not a problem. The platform is Linux, but I'd /
much/ rather not write platform dependent code (spent too much time
porting software).

Rick Jones

unread,
Sep 21, 2010, 1:03:23 PM9/21/10
to
Martin Bonner <martin...@yahoo.co.uk> wrote:
> On Sep 20, 6:15?pm, David Schwartz <dav...@webmaster.com> wrote:
> > On Sep 20, 10:06?am, Martin Bonner <martinfro...@yahoo.co.uk> wrote:
> >
> > > I'm writing a socket proxy. ?If I call recv on one thread, and send on

> > > another, do I risk reading my own data (as opposed to sending the data
> > > to the other end of the socket, and then reading the reply)?
> >
> > Not for TCP or unicast UDP on any sensible platform.
> >

> Thank you (and Rainer). That was the answer I was hoping for. I'm
> using TCP, so that's not a problem. The platform is Linux, but I'd /
> much/ rather not write platform dependent code (spent too much time
> porting software).

Where you may (will?) run into portability issues will be when you do
things like call close() in one thread while another thread is blocked
in a recv() call or somesuch.

rick jones
--
It is not a question of half full or empty - the glass has a leak.
The real question is "Can it be patched?"
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...

David Schwartz

unread,
Sep 21, 2010, 5:58:00 PM9/21/10
to
On Sep 21, 10:03 am, Rick Jones <rick.jon...@hp.com> wrote:

> Where you may (will?) run into portability issues will be when you do
> things like call close() in one thread while another thread is blocked
> in a recv() call or somesuch.

It's not possible to do this. At least, there is no portable way to do
it. Try to write portable code that calls 'close' in one thread while
another thread is blocked in 'recv' -- it cannot be done. There is no
way you can possibly know another thread is actually blocked in 'recv'
as opposed to about to block in 'recv'.

Any code that could call 'close' while another thread is blocked on
'recv' for the same descriptor could call 'close' just before the
other thread calls 'recv'. And that's fatal. So any code that could be
broken this way would already necessarily be broken in a much worse
way.

DS

Scott Lurndal

unread,
Sep 21, 2010, 6:57:41 PM9/21/10
to
David Schwartz <dav...@webmaster.com> writes:

>On Sep 21, 10:03=A0am, Rick Jones <rick.jon...@hp.com> wrote:
>
>> Where you may (will?) run into portability issues will be when you do
>> things like call close() in one thread while another thread is blocked
>> in a recv() call or somesuch.
>
>It's not possible to do this. At least, there is no portable way to do
>it. Try to write portable code that calls 'close' in one thread while
>another thread is blocked in 'recv' -- it cannot be done. There is no
>way you can possibly know another thread is actually blocked in 'recv'
>as opposed to about to block in 'recv'.

I think Rick's point was that if one thread calls close while other
threads are processing, you may end up with a situation where close
is called _while_ a thread is blocked in recieve. The resulting
system behavior is not specified.

scott

David Schwartz

unread,
Sep 21, 2010, 7:05:13 PM9/21/10
to
On Sep 21, 3:57 pm, sc...@slp53.sl.home (Scott Lurndal) wrote:

> I think Rick's point was that if one thread calls close while other
> threads are processing, you may end up with a situation where close
> is called _while_ a thread is blocked in recieve. The resulting
> system behavior is not specified.

Right, but any such code also may call 'close' just before a thread
calls 'recv'. That behavior is *definitely* not specified and
obviously disastrous. So this can only be an issue in code that's
horribly broken for other reasons anyway.

DS

Rick Jones

unread,
Sep 21, 2010, 7:25:18 PM9/21/10
to
David Schwartz <dav...@webmaster.com> wrote:
> Right, but any such code also may call 'close' just before a thread
> calls 'recv'. That behavior is *definitely* not specified and
> obviously disastrous. So this can only be an issue in code that's
> horribly broken for other reasons anyway.

I've not been down a rathole for a while so... I'll quibble about
degrees.

I'm not sure it is "obviously disastrous." The level of disaster
depends on the platform-specific behaviour and how the application is
coded. If it treats the error return from recv() as a fatal error
then sure, it is a disaster. If it simply treats the error return
from recv() as a "bummer, it failed" sort of thing, I'm not certain it
is a disaster. It is still not good, IMO.

Now, if we go a step further, and have one thread waiting to call
recv(), and another calls close(), and then it or yet another thread
calls socket() or accept() and the fd gets reassigned before the first
gets to its recv() call... that I will agree is well and truly a
disaster :)

rick jones
--
a wide gulf separates "what if" from "if only"

David Schwartz

unread,
Sep 21, 2010, 8:44:21 PM9/21/10
to
On Sep 21, 4:25 pm, Rick Jones <rick.jon...@hp.com> wrote:

> I'm not sure it is "obviously disastrous."  The level of disaster
> depends on the platform-specific behaviour and how the application is
> coded.  If it treats the error return from recv() as a fatal error
> then sure, it is a disaster.  If it simply treats the error return
> from recv() as a "bummer, it failed" sort of thing, I'm not certain it
> is a disaster.  It is still not good, IMO.

There's no guarantee it will fail. It could succeed and receive data
from an unrelated connection. If this connection was owned by a system
library, the result could be disastrous.

> Now, if we go a step further, and have one thread waiting to call
> recv(), and another calls close(), and then it or yet another thread
> calls socket() or accept() and the fd gets reassigned before the first
> gets to its recv() call... that I will agree is well and truly a
> disaster :)

There's no way you can prevent that. The system's thread management
library may open a socket for its own reasons, for example.

DS

Martin Bonner

unread,
Sep 22, 2010, 4:34:40 AM9/22/10
to
On Sep 21, 10:58 pm, David Schwartz <dav...@webmaster.com> wrote:
> On Sep 21, 10:03 am, Rick Jones <rick.jon...@hp.com> wrote:
>
> > Where you may (will?) run into portability issues will be when you do
> > things like call close() in one thread while another thread is blocked
> > in a recv() call or somesuch.
>
> any code that could be broken this way would already necessarily
> be broken in a much worse way.

Don'cha just love multi-threaded programming!

Thanks guys. I would have blindly walked into both those elephant
traps. What's more, I'm pretty sure testing would have passed without
problems, and we wouldn't have seen anything go wrong until either a)
a demo in front of a major company; b) deployment in a concrete bunker
in the back end of nowhere.

Christof Meerwald

unread,
Sep 22, 2010, 8:14:20 AM9/22/10
to
On Tue, 21 Sep 2010 17:03:23 +0000 (UTC), Rick Jones wrote:
> Where you may (will?) run into portability issues will be when you do
> things like call close() in one thread while another thread is blocked
> in a recv() call or somesuch.

Did you actually mean shutdown instead of close? Which is less
dangerous, but (I think) still non-portable.


Christof

--
http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

David Schwartz

unread,
Sep 22, 2010, 9:59:36 AM9/22/10
to
On Sep 22, 5:14 am, Christof Meerwald <NOSPAM-seeMySig
+ue...@usenet.cmeerw.org> wrote:

> Did you actually mean shutdown instead of close? Which is less
> dangerous, but (I think) still non-portable.

Doing a 'shutdown' in one thread while doing other operations in
another thread is safe and portable.

DS

Martin Bonner

unread,
Sep 22, 2010, 12:49:55 PM9/22/10
to

If I shutdown a socket in one thread, while calling recv in another,
will the recv return, or will it block?

Rainer Weikusat

unread,
Sep 22, 2010, 1:12:11 PM9/22/10
to
Martin Bonner <martin...@yahoo.co.uk> writes:
> On Sep 22, 2:59�pm, David Schwartz <dav...@webmaster.com> wrote:
>> On Sep 22, 5:14�am, Christof Meerwald <NOSPAM-seeMySig
>>
>> +ue...@usenet.cmeerw.org> wrote:
>> > Did you actually mean shutdown instead of close? Which is less
>> > dangerous, but (I think) still non-portable.
>>
>> Doing a 'shutdown' in one thread while doing other operations in
>> another thread is safe and portable.
>
> If I shutdown a socket in one thread, while calling recv in another,
> will the recv return, or will it block?

Provided that TCP is being used, it should return and indicate that 0
bytes were read.

Christof Meerwald

unread,
Sep 22, 2010, 2:43:47 PM9/22/10
to
On Wed, 22 Sep 2010 09:49:55 -0700 (PDT), Martin Bonner wrote:
> On Sep 22, 2:59 pm, David Schwartz <dav...@webmaster.com> wrote:
>> On Sep 22, 5:14 am, Christof Meerwald <NOSPAM-seeMySig
>> +ue...@usenet.cmeerw.org> wrote:
>> > Did you actually mean shutdown instead of close? Which is less
>> > dangerous, but (I think) still non-portable.
>> Doing a 'shutdown' in one thread while doing other operations in
>> another thread is safe and portable.
> If I shutdown a socket in one thread, while calling recv in another,
> will the recv return, or will it block?

Well, that's actually the non-portable bit here. While it might be a
sensible thing to expect, it doesn't work on all platforms, see

http://www.omniorb-support.com/pipermail/omniorb-list/2000-June/015561.html
http://www.omniorb-support.com/pipermail/omniorb-list/2002-March/020428.html

Rick Jones

unread,
Sep 22, 2010, 4:24:02 PM9/22/10
to
> >> Doing a 'shutdown' in one thread while doing other operations in
> >> another thread is safe and portable.
> >
> > If I shutdown a socket in one thread, while calling recv in another,
> > will the recv return, or will it block?

> Provided that TCP is being used, it should return and indicate that 0
> bytes were read.

If it included SHUT_RD I presume. If it was just a SHUT_WR I would
not expect a read return of zero.

Do verify that on a couple stacks though... both the RD vs WR bit, and
whether the shutdown() while recv() is indeed portable in the first
place.

FWIW, while I do not know that such a universe exists, I could imagine
one where one could shutdown(SHUT_RDWR) a socket and then connect()
that socket someplace else entirely, which, I think, brings us right
back to the issues surrounding calling close() in one thread just
before another calls recv()...

rick jones
--
Wisdom Teeth are impacted, people are affected by the effects of events.

David Schwartz

unread,
Sep 22, 2010, 7:02:00 PM9/22/10
to
On Sep 22, 9:49 am, Martin Bonner <martinfro...@yahoo.co.uk> wrote:

> If I shutdown a socket in one thread, while calling recv in another,
> will the recv return, or will it block?

If we're talking about a TCP socket, if 'recv' does not return, the
platform is hopelessly broken. This is not just for multi-threaded
code, you can do this same thing with single-threaded code. (A socket
can be shared across processes.)

DS

0 new messages