]> Cypherpunks repositories - gostls13.git/commitdiff
internal/poll: don't use r/w lock for Pread/Pwrite
authorIan Lance Taylor <iant@golang.org>
Tue, 25 Apr 2017 04:01:08 +0000 (21:01 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 25 Apr 2017 04:29:39 +0000 (04:29 +0000)
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: Brad Fitzpatrick <bradfitz@golang.org>
src/internal/poll/fd_unix.go
src/internal/poll/fd_windows.go

index f3e3c53d65cb9a4750157ef87a3c7d74bb03eebd..c461f04c398bc1371040f8553085d58bfde204c3 100644 (file)
@@ -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
                }
index 89a4ea904c53efa8b2af049572cc818ede47647b..4d7ec686d4eb50ab39c35d86ea2c4d9535d64fba 100644 (file)
@@ -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()