This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: simultaneous socket write/close causes panic?
>>>>> "Nick" == Nick Garnett <nickg@ecoscentric.com> writes:
Nick> Bart Veer <bartv@ecoscentric.com> writes:
<snip>
>> Similarly the concurrent write/close is fundamentally broken.
>> Sometimes the application can get away with it, sometimes you will get
>> sensible error codes, sometimes the system will crash - in this case,
>> raise a panic. The fault is with the application developer, not with
>> the TCP/IP stack. Admittedly more programmers will have experience
>> with memory corruption bugs than with the subtleties of socket
>> programming.
Nick> This is not really an application problem -- there's nothing
Nick> wrong about an application expecting this to work. Socket
Nick> calls should, as as has already been pointed out elsewhere,
Nick> be atomic with respect to eachother. In the scenario that we
Nick> are considering, either the close happens first, in which
Nick> case the write will return an error; or the write will
Nick> happen first, in which case the close will flush the data
Nick> and successfully close the stream.
It is an application problem because a third thread may cause the file
descriptor to be reallocated, e.g. by a concurrent call to connect()
or accept(). So you could end up with the sequence
close()/accept()/write() and the data going to some random
destination. No amount of locking within eCos can prevent this, it has
to be addressed at the application level.
Nick> I can see plenty of situations where closing a socket from
Nick> another thread is a legitimate response to some error
Nick> situation. Although I would hope that a well behaved program
Nick> would normally shut a stream down in a more controlled
Nick> manner.
I agree that there are such situations, but I don't believe close() is
the right tool for the job here. Instead the code that detects the
error condition should call shutdown() with SHUT_RDWR. I think (but
have not verified) that should abort any concurrent read() or write()
calls, and cause subsequent calls to fail. Then when all threads using
the socket are aware of the error condition and will no longer attempt
communication via the file descriptor, then the close() can happen
safely.
Bart
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss