1// Copyright 2022 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package os 6 7// File locking support for Plan 9. This uses fdMutex from the 8// internal/poll package. 9 10// incref adds a reference to the file. It returns an error if the file 11// is already closed. This method is on File so that we can incorporate 12// a nil test. 13func (f *File) incref(op string) (err error) { 14 if f == nil { 15 return ErrInvalid 16 } 17 if !f.fdmu.Incref() { 18 err = ErrClosed 19 if op != "" { 20 err = &PathError{Op: op, Path: f.name, Err: err} 21 } 22 } 23 return err 24} 25 26// decref removes a reference to the file. If this is the last 27// remaining reference, and the file has been marked to be closed, 28// then actually close it. 29func (file *file) decref() error { 30 if file.fdmu.Decref() { 31 return file.destroy() 32 } 33 return nil 34} 35 36// readLock adds a reference to the file and locks it for reading. 37// It returns an error if the file is already closed. 38func (file *file) readLock() error { 39 if !file.fdmu.ReadLock() { 40 return ErrClosed 41 } 42 return nil 43} 44 45// readUnlock removes a reference from the file and unlocks it for reading. 46// It also closes the file if it marked as closed and there is no remaining 47// reference. 48func (file *file) readUnlock() { 49 if file.fdmu.ReadUnlock() { 50 file.destroy() 51 } 52} 53 54// writeLock adds a reference to the file and locks it for writing. 55// It returns an error if the file is already closed. 56func (file *file) writeLock() error { 57 if !file.fdmu.WriteLock() { 58 return ErrClosed 59 } 60 return nil 61} 62 63// writeUnlock removes a reference from the file and unlocks it for writing. 64// It also closes the file if it is marked as closed and there is no remaining 65// reference. 66func (file *file) writeUnlock() { 67 if file.fdmu.WriteUnlock() { 68 file.destroy() 69 } 70} 71