This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Thread-Safe stdio files
- From: Kelvin Lawson <klawson at ad-holdings dot co dot uk>
- To: ecos-discuss at sources dot redhat dot com
- Date: Fri, 02 Apr 2004 17:04:52 +0100
- Subject: [ECOS] Thread-Safe stdio files
Hi All,
I've come across a problem with cyg_libc_stdio_flush_all_but().
This function walks the list of streams without first taking the
Cyg_libc_stdio_files mutex. If I carry out a lot of file IO, then quite
often I end up with corrupted stream pointers. (Assert fails with
"Stream object is not a valid stream!")
This has been discussed before on the list but with no conclusion:
http://sources.redhat.com/ml/ecos-discuss/2003-12/msg00132.html
I have temporarily fixed the corrupted stream problem by protecting the
entire list-walk with Cyg_libc_stdio_files::lock(). However I believe
this could result in deadlock due to the order of mutex-taking. The
poster of the message above in fact did get deadlocks, though they
didn't protect the list in the same way.
fopen() and fclose() both take the stdio file lock, then later take the
stream lock. However certain code paths will take these mutexes in the
opposite order:
fopen():
stdio_file::lock()
stream::lock()
...
stream::unlock()
stdio_file::unlock()
fgets():
stream::lock()
stdio_file::lock()
...
stdio_file::lock()
stream::lock()
Therefore I don't think it's safe to take the stdio_file mutex in
cyg_libc_stdio_flush_all_but().
I don't particularly like the idea of modifying all code that takes the
stream lock to take the stdio_file lock first. Does anyone have any
thoughts about a good solution to this ?
I have currently disabled the call to cyg_libc_stdio_flush_all_but() -
I'd also be interested to know why this is done in the
refill_read_buffer() call.
Cheers,
Kelvin.
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss