mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 09:41:44 +08:00
vfs: keep track of number of open RWHandles
This commit is contained in:
parent
5e334eedd2
commit
9b011ce7e4
26
vfs/file.go
26
vfs/file.go
|
@ -21,6 +21,7 @@ type File struct {
|
|||
mu sync.Mutex // protects the following
|
||||
o fs.Object // NB o may be nil if file is being written
|
||||
leaf string // leaf name of the object
|
||||
rwOpenCount int // number of open files on this handle
|
||||
writers []Handle // writers for this file
|
||||
readWriters int // how many RWFileHandle are open for writing
|
||||
readWriterClosing bool // is a RWFileHandle currently cosing?
|
||||
|
@ -138,6 +139,31 @@ func (f *File) delWriter(h Handle, modifiedCacheFile bool) (lastWriterAndModifie
|
|||
return
|
||||
}
|
||||
|
||||
// addRWOpen should be called by ReadWriteHandle when they have
|
||||
// actually opened the file for read or write.
|
||||
func (f *File) addRWOpen() {
|
||||
f.mu.Lock()
|
||||
f.rwOpenCount++
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// delRWOpen should be called by ReadWriteHandle when they have closed
|
||||
// an actually opene file for read or write.
|
||||
func (f *File) delRWOpen() {
|
||||
f.mu.Lock()
|
||||
f.rwOpenCount--
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
// rwOpens returns how many active open ReadWriteHandles there are.
|
||||
// Note that file handles which are in pending open state aren't
|
||||
// counted.
|
||||
func (f *File) rwOpens() int {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
return f.rwOpenCount
|
||||
}
|
||||
|
||||
// finishWriterClose resets the readWriterClosing flag
|
||||
func (f *File) finishWriterClose() {
|
||||
f.mu.Lock()
|
||||
|
|
|
@ -192,6 +192,7 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) {
|
|||
}
|
||||
fh.File = fd
|
||||
fh.opened = true
|
||||
fh.file.addRWOpen()
|
||||
fh.d.addObject(fh.file) // make sure the directory has this object in it now
|
||||
return nil
|
||||
}
|
||||
|
@ -246,7 +247,12 @@ func (fh *RWFileHandle) close() (err error) {
|
|||
return ECLOSED
|
||||
}
|
||||
fh.closed = true
|
||||
defer fh.d.vfs.cache.close(fh.remote)
|
||||
defer func() {
|
||||
if fh.opened {
|
||||
fh.file.delRWOpen()
|
||||
}
|
||||
fh.d.vfs.cache.close(fh.remote)
|
||||
}()
|
||||
rdwrMode := fh.flags & accessModeMask
|
||||
writer := rdwrMode != os.O_RDONLY
|
||||
|
||||
|
|
|
@ -74,9 +74,15 @@ func TestRWFileHandleMethodsRead(t *testing.T) {
|
|||
// Size
|
||||
assert.Equal(t, int64(16), fh.Size())
|
||||
|
||||
// No opens yet
|
||||
assert.Equal(t, 0, fh.file.rwOpens())
|
||||
|
||||
// Read 1
|
||||
assert.Equal(t, "0", rwReadString(t, fh, 1))
|
||||
|
||||
// Open after the read
|
||||
assert.Equal(t, 1, fh.file.rwOpens())
|
||||
|
||||
// Read remainder
|
||||
assert.Equal(t, "123456789abcdef", rwReadString(t, fh, 256))
|
||||
|
||||
|
@ -101,6 +107,9 @@ func TestRWFileHandleMethodsRead(t *testing.T) {
|
|||
assert.Equal(t, nil, fh.Close())
|
||||
assert.True(t, fh.closed)
|
||||
|
||||
// No opens again
|
||||
assert.Equal(t, 0, fh.file.rwOpens())
|
||||
|
||||
// Close again
|
||||
assert.Equal(t, ECLOSED, fh.Close())
|
||||
}
|
||||
|
@ -266,6 +275,10 @@ func TestRWFileHandleMethodsWrite(t *testing.T) {
|
|||
vfs, fh := rwHandleCreateWriteOnly(t, r)
|
||||
defer cleanup(t, r, vfs)
|
||||
|
||||
// 1 opens since we opened with O_CREATE and the file didn't
|
||||
// exist in the cache
|
||||
assert.Equal(t, 1, fh.file.rwOpens())
|
||||
|
||||
// String
|
||||
assert.Equal(t, "file1 (rw)", fh.String())
|
||||
assert.Equal(t, "<nil *RWFileHandle>", (*RWFileHandle)(nil).String())
|
||||
|
@ -293,6 +306,9 @@ func TestRWFileHandleMethodsWrite(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, 5, n)
|
||||
|
||||
// Open after the write
|
||||
assert.Equal(t, 1, fh.file.rwOpens())
|
||||
|
||||
// Offset #2
|
||||
assert.Equal(t, int64(5), offset())
|
||||
assert.Equal(t, int64(5), node.Size())
|
||||
|
@ -323,6 +339,9 @@ func TestRWFileHandleMethodsWrite(t *testing.T) {
|
|||
// Close
|
||||
assert.NoError(t, fh.Close())
|
||||
|
||||
// No opens again
|
||||
assert.Equal(t, 0, fh.file.rwOpens())
|
||||
|
||||
// Check double close
|
||||
err = fh.Close()
|
||||
assert.Equal(t, ECLOSED, err)
|
||||
|
|
Loading…
Reference in New Issue
Block a user