views:

63

answers:

3

What will happen if fwrite & fclose are called in parallel from two threads for the same file descriptor?

+4  A: 

fwrite and fclose operate on the FILE data structure. Since this is a largish data structure that does store more than just the file descriptor, the answer is bad things.

Don't do this unless you ensure atomic operation using mutexes.

doron
This is incorrect, sort of. FILEs contain a mutex for thread-safety, assuming you have a correct POSIX implementation. Either your fwrite will go through entirely (or stop for reasons unrelated to thread safety, like a full disk), or it will have been fclosed() and you will get undefined behavior. But it can't fclose in the middle of a write.
Joe
-1 for explaining with guesswork and ending up with the wrong reasons why the OP can't use `fwrite` and `fclose` simultaneously. POSIX requires thread-safe `FILE` operations; the problem is that, if another thread may have called `fclose`, then you're potentially passing an invalid pointer to `fwrite` which results in undefined behavior.
R..
@Joe, since there's no way to determine if you're "in the middle of a write", and since any program which can call `fclose` while `fwrite` is in progress could have instead called `fwrite` just after `fclose` finished (purely timing differences), I see no reason for an implementation to include any locking at all in `fclose`. The program already has undefined behavior and you might as well just let it crash and burn.
R..
I have been looking at the source code for fwrite to understand the locking. Interestingly enough there is no locking of fwrite in Android and although the eglibc (used by Ubuntu) implementation has some sort of lock. I am still trying to see exactly how it works.
doron
@R.: I am not sure that is correct. Imagine a system of three threads; one writes "endfoobar" to FILE *x. Another is reading it three characters at a time; upon reading "end" it signals the third thread, which calls fclose(x), and stops reading. fclose may trigger the fwrite to end in a defined way early (e.g. EPIPE), but it must still synchronize with it to do that. I'm describing a fairly pathological program, but I believe it means fclose needs some level of synchronization.
Joe
A: 

For such a circumstance you need to define priorities of your methods. You can control the methods with "synchronized".

telvin
This is C not Java. There is no "synchronized" in C
doron
+3  A: 

POSIX requires FILE access to be thread-safe, but since fclose closes the file and invalidates the pointer, there is no way (i.e. it's not just a specification issue but a fundamental API issue that could never be "fixed" or made to go away) to use fclose when another thread might be accessing the FILE still. You'll need to do your own locking.

R..