Commit b0472e22 authored by Ian Lance Taylor's avatar Ian Lance Taylor

internal/poll: don't use r/w lock for Pread/Pwrite

Since Pread/Pwrite specify a file offset, using incref is sufficient.
This permits multiple Pread/Pwrite calls in parallel.

Since Pread/Pwrite specify a file offset, it doesn't seem to make
sense to use the poller for them, so don't.

Updates #19586

Change-Id: I676be16bf519b9a45f8e6b1d991c44f10848bc11
Reviewed-on: https://go-review.googlesource.com/41670
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8ae60dc1
......@@ -122,29 +122,22 @@ func (fd *FD) Read(p []byte) (int, error) {
// Pread wraps the pread system call.
func (fd *FD) Pread(p []byte, off int64) (int, error) {
if err := fd.readLock(); err != nil {
return 0, err
}
defer fd.readUnlock()
if err := fd.pd.prepareRead(); err != nil {
// Call incref, not readLock, because since pread specifies the
// offset it is independent from other reads.
// Similarly, using the poller doesn't make sense for pread.
if err := fd.incref(); err != nil {
return 0, err
}
if fd.IsStream && len(p) > maxRW {
p = p[:maxRW]
}
for {
n, err := syscall.Pread(fd.Sysfd, p, off)
if err != nil {
n = 0
if err == syscall.EAGAIN {
if err = fd.pd.waitRead(); err == nil {
continue
}
}
}
err = fd.eofError(n, err)
return n, err
n, err := syscall.Pread(fd.Sysfd, p, off)
if err != nil {
n = 0
}
fd.decref()
err = fd.eofError(n, err)
return n, err
}
// ReadFrom wraps the recvfrom network call.
......@@ -233,13 +226,13 @@ func (fd *FD) Write(p []byte) (int, error) {
// Pwrite wraps the pwrite system call.
func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
if err := fd.writeLock(); err != nil {
return 0, err
}
defer fd.writeUnlock()
if err := fd.pd.prepareWrite(); err != nil {
// Call incref, not writeLock, because since pwrite specifies the
// offset it is independent from other writes.
// Similarly, using the poller doesn't make sense for pwrite.
if err := fd.incref(); err != nil {
return 0, err
}
defer fd.decref()
var nn int
for {
max := len(p)
......@@ -253,11 +246,6 @@ func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
if nn == len(p) {
return nn, err
}
if err == syscall.EAGAIN {
if err = fd.pd.waitWrite(); err == nil {
continue
}
}
if err != nil {
return nn, err
}
......
......@@ -509,10 +509,12 @@ func (fd *FD) readConsole(b []byte) (int, error) {
// Pread emulates the Unix pread system call.
func (fd *FD) Pread(b []byte, off int64) (int, error) {
if err := fd.readLock(); err != nil {
// Call incref, not readLock, because since pread specifies the
// offset it is independent from other reads.
if err := fd.incref(); err != nil {
return 0, err
}
defer fd.readUnlock()
defer fd.decref()
fd.l.Lock()
defer fd.l.Unlock()
......@@ -643,10 +645,12 @@ func (fd *FD) writeConsole(b []byte) (int, error) {
// Pwrite emulates the Unix pwrite system call.
func (fd *FD) Pwrite(b []byte, off int64) (int, error) {
if err := fd.writeLock(); err != nil {
// Call incref, not writeLock, because since pwrite specifies the
// offset it is independent from other writes.
if err := fd.incref(); err != nil {
return 0, err
}
defer fd.writeUnlock()
defer fd.decref()
fd.l.Lock()
defer fd.l.Unlock()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment