Generally, no, but there are some exceptions (IIRC, multicast messages
and packet sockets).
Not for TCP or unicast UDP on any sensible platform.
DS
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).
> 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...
> 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
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
> 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
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"
> 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
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.
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
> 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
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.
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
> 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.
> 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