]> Cypherpunks repositories - gostls13.git/commitdiff
net: implement cancellable lookup on Plan 9
authorDavid du Colombier <0intro@gmail.com>
Sun, 13 May 2018 20:58:31 +0000 (22:58 +0200)
committerDavid du Colombier <0intro@gmail.com>
Sun, 13 May 2018 21:28:12 +0000 (21:28 +0000)
This change implements cancellable lookup
on Plan 9. The query function has been modified
to return when the ctx.Done channel is closed.

Fixes #25361.

Change-Id: I544b779ceec8d69975bc7363045849c21cbfd59e
Reviewed-on: https://go-review.googlesource.com/112981
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/lookup_plan9.go

index 1037b81a3be96f9c0396142a1f1c0774c7448bd1..e0b38c69b99ddd0d0c050e566748a6f8b881313a 100644 (file)
@@ -11,34 +11,58 @@ import (
        "os"
 )
 
-func query(ctx context.Context, filename, query string, bufSize int) (res []string, err error) {
-       file, err := os.OpenFile(filename, os.O_RDWR, 0)
-       if err != nil {
-               return
-       }
-       defer file.Close()
+func query(ctx context.Context, filename, query string, bufSize int) (addrs []string, err error) {
+       queryAddrs := func() (addrs []string, err error) {
+               file, err := os.OpenFile(filename, os.O_RDWR, 0)
+               if err != nil {
+                       return nil, err
+               }
+               defer file.Close()
 
-       _, err = file.Seek(0, io.SeekStart)
-       if err != nil {
-               return
-       }
-       _, err = file.WriteString(query)
-       if err != nil {
-               return
+               _, err = file.Seek(0, io.SeekStart)
+               if err != nil {
+                       return nil, err
+               }
+               _, err = file.WriteString(query)
+               if err != nil {
+                       return nil, err
+               }
+               _, err = file.Seek(0, io.SeekStart)
+               if err != nil {
+                       return nil, err
+               }
+               buf := make([]byte, bufSize)
+               for {
+                       n, _ := file.Read(buf)
+                       if n <= 0 {
+                               break
+                       }
+                       addrs = append(addrs, string(buf[:n]))
+               }
+               return addrs, nil
        }
-       _, err = file.Seek(0, io.SeekStart)
-       if err != nil {
-               return
+
+       type ret struct {
+               addrs []string
+               err   error
        }
-       buf := make([]byte, bufSize)
-       for {
-               n, _ := file.Read(buf)
-               if n <= 0 {
-                       break
+
+       ch := make(chan ret, 1)
+       go func() {
+               addrs, err := queryAddrs()
+               ch <- ret{addrs: addrs, err: err}
+       }()
+
+       select {
+       case r := <-ch:
+               return r.addrs, r.err
+       case <-ctx.Done():
+               return nil, &DNSError{
+                       Name:      query,
+                       Err:       ctx.Err().Error(),
+                       IsTimeout: ctx.Err() == context.DeadlineExceeded,
                }
-               res = append(res, string(buf[:n]))
        }
-       return
 }
 
 func queryCS(ctx context.Context, net, host, service string) (res []string, err error) {