-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
os: use poll.fdMutex for Plan 9 files
This permits us to safely support concurrent access to files on Plan 9. Concurrent access was already safe on other systems. This does introduce a change: if one goroutine calls a blocking read on a pipe, and another goroutine closes the pipe, then before this CL the close would occur. Now the close will be delayed until the blocking read completes. Also add tests that concurrent I/O and Close on a pipe are OK. For #50436 For #56043 Change-Id: I969c869ea3b8c5c2f2ef319e441a56a3c64e7bf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/438347 Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: David du Colombier <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
- Loading branch information
1 parent
669ec54
commit 4fe1971
Showing
8 changed files
with
306 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package poll | ||
|
||
// Expose fdMutex for use by the os package on Plan 9. | ||
// On Plan 9 we don't want to use async I/O for file operations, | ||
// but we still want the locking semantics that fdMutex provides. | ||
|
||
// FDMutex is an exported fdMutex, only for Plan 9. | ||
type FDMutex struct { | ||
fdmu fdMutex | ||
} | ||
|
||
func (fdmu *FDMutex) Incref() bool { | ||
return fdmu.fdmu.incref() | ||
} | ||
|
||
func (fdmu *FDMutex) Decref() bool { | ||
return fdmu.fdmu.decref() | ||
} | ||
|
||
func (fdmu *FDMutex) IncrefAndClose() bool { | ||
return fdmu.fdmu.increfAndClose() | ||
} | ||
|
||
func (fdmu *FDMutex) ReadLock() bool { | ||
return fdmu.fdmu.rwlock(true) | ||
} | ||
|
||
func (fdmu *FDMutex) ReadUnlock() bool { | ||
return fdmu.fdmu.rwunlock(true) | ||
} | ||
|
||
func (fdmu *FDMutex) WriteLock() bool { | ||
return fdmu.fdmu.rwlock(false) | ||
} | ||
|
||
func (fdmu *FDMutex) WriteUnlock() bool { | ||
return fdmu.fdmu.rwunlock(false) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package os | ||
|
||
// File locking support for Plan 9. This uses fdMutex from the | ||
// internal/poll package. | ||
|
||
// incref adds a reference to the file. It returns an error if the file | ||
// is already closed. This method is on File so that we can incorporate | ||
// a nil test. | ||
func (f *File) incref(op string) (err error) { | ||
if f == nil { | ||
return ErrInvalid | ||
} | ||
if !f.fdmu.Incref() { | ||
err = ErrClosed | ||
if op != "" { | ||
err = &PathError{Op: op, Path: f.name, Err: err} | ||
} | ||
} | ||
return err | ||
} | ||
|
||
// decref removes a reference to the file. If this is the last | ||
// remaining reference, and the file has been marked to be closed, | ||
// then actually close it. | ||
func (file *file) decref() error { | ||
if file.fdmu.Decref() { | ||
return file.destroy() | ||
} | ||
return nil | ||
} | ||
|
||
// readLock adds a reference to the file and locks it for reading. | ||
// It returns an error if the file is already closed. | ||
func (file *file) readLock() error { | ||
if !file.fdmu.ReadLock() { | ||
return ErrClosed | ||
} | ||
return nil | ||
} | ||
|
||
// readUnlock removes a reference from the file and unlocks it for reading. | ||
// It also closes the file if it marked as closed and there is no remaining | ||
// reference. | ||
func (file *file) readUnlock() { | ||
if file.fdmu.ReadUnlock() { | ||
file.destroy() | ||
} | ||
} | ||
|
||
// writeLock adds a reference to the file and locks it for writing. | ||
// It returns an error if the file is already closed. | ||
func (file *file) writeLock() error { | ||
if !file.fdmu.WriteLock() { | ||
return ErrClosed | ||
} | ||
return nil | ||
} | ||
|
||
// writeUnlock removes a reference from the file and unlocks it for writing. | ||
// It also closes the file if it is marked as closed and there is no remaining | ||
// reference. | ||
func (file *file) writeUnlock() { | ||
if file.fdmu.WriteUnlock() { | ||
file.destroy() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.