Thread-Safe FileStreams

Mark Guzdial guzdial at cc.gatech.edu
Mon Apr 6 15:53:02 UTC 1998


Over on the PWS mailing list (pws at cc.gatech.edu), we've been investigating
Squeak's file system under thread access.  If process 1 opens the file,
then process 2 opens the file, then process 1 closes the file, then process
2 closes the file, what happens?  The short answer is that you get a
primitive failure, but if you do this long enough and ignore the errors
(through exception handling), you end up leaking all the file handles.  The
code at the bottom of this message, run a couple times, uses up all the
filehandles on a PowerMac 6100 running Jitter 1.31 under System 7.6.1.

I am interested in what the solution is to this problem, but don't know
enough about thread-safe file systems to know what the right level to
attack the problem is.  Is it:
- An OS issue?  Can UNIX handle this better than Macs can?
- A VM or Image issue?  Making file access, even for reads, mutually
exclusive seems harsh.  Maybe I can detect multiple opens to the same file
for reading, then just buffer the reads?
- An application issue?  Clearly, for multiple writes, it's the
application's job to make sure that they are serialized.  Maybe the
application has to serialize reads, too, since I can't know at open time if
the access is read only or read-write.

I'd be interested in hearing your suggestions!

Mark


--- CODE TO LEAK THE FILE HANDLES ----

| aFile |
"Put something in the file"
aFile _ FileStream fileNamed: 'fred.test'.
1 to: 100 do: [:i | aFile nextPutAll: (i printString); cr.].
aFile close.

"Stress test"
[1 to: 50 do:
		[:i |
		Transcript show: 'Process 1 ',i printString,'-'.
		[(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile _ FileStream fileNamed: 'fred.test'.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile contentsOfEntireFile.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile close.] ifError: [:r :c | Transcript show: (c
printString), (r printString); cr.]]] fork.
[1 to: 50 do:
		[:j |
		Transcript show: 'Process 2 ',j printString,'-'.
		[(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile _ FileStream fileNamed: 'fred.test'.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile contentsOfEntireFile.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile close.] ifError: [:r :c | Transcript show: (c
printString), (r printString); cr.]]] fork.
[1 to: 100 do:
		[:i |
		Transcript show: 'Process 3 ',i printString,'-'.
		[(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile _ FileStream fileNamed: 'fred.test'.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile contentsOfEntireFile.
		(Delay forMilliseconds: (100 to: 500) atRandom) wait.
		aFile close.] ifError: [:r :c | Transcript show: (c
printString), (r printString); cr.]]] fork.

--------------------------
Mark Guzdial : Georgia Tech : College of Computing : Atlanta, GA 30332-0280
(404) 894-5618 : Fax (404) 894-0673 : guzdial at cc.gatech.edu
http://www.cc.gatech.edu/gvu/people/Faculty/Mark.Guzdial.html





More information about the Squeak-dev mailing list