input := make([]byte, len(tt.input))
                copy(input, tt.input)
                rc := nopWriteCloser{bytes.NewReader(input)}
-               done := make(chan bool)
+               done := make(chan struct{})
                c := newChild(rc, http.HandlerFunc(func(
                        w http.ResponseWriter,
                        r *http.Request,
                                t.Errorf("Expected %#v, got %#v", tt.err, err)
                        }
                        // not reached if body of request isn't closed
-                       done <- true
+                       close(done)
                }))
-               go c.serve()
+               c.serve()
                // wait for body of request to be closed or all goroutines to block
                <-done
        }
                input := make([]byte, len(tt.input))
                copy(input, tt.input)
                rc := nopWriteCloser{bytes.NewReader(input)}
-               done := make(chan bool)
+               done := make(chan struct{})
                c := newChild(rc, http.HandlerFunc(func(
                        w http.ResponseWriter,
                        r *http.Request,
                        } else if env[tt.envVar] != tt.expectedVal {
                                t.Errorf("Expected %s, got %s", tt.expectedVal, env[tt.envVar])
                        }
-                       done <- true
+                       close(done)
                }))
-               go c.serve()
+               c.serve()
                <-done
        }
 }
                        input := make([]byte, len(streamFullRequestStdin))
                        copy(input, streamFullRequestStdin)
                        rc := nopWriteCloser{bytes.NewReader(input)}
-                       done := make(chan bool)
+                       done := make(chan struct{})
                        var resp *response
                        c := newChild(rc, http.HandlerFunc(func(
                                w http.ResponseWriter,
                        ) {
                                io.WriteString(w, tt.body)
                                resp = w.(*response)
-                               done <- true
+                               close(done)
                        }))
-                       defer c.cleanUp()
-                       go c.serve()
+                       c.serve()
                        <-done
                        if got := resp.Header().Get("Content-Type"); got != tt.wantCT {
                                t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT)
        }
 }
 
-type signalingNopCloser struct {
-       io.Reader
+type signalingNopWriteCloser struct {
+       io.ReadCloser
        closed chan bool
 }
 
-func (*signalingNopCloser) Write(buf []byte) (int, error) {
+func (*signalingNopWriteCloser) Write(buf []byte) (int, error) {
        return len(buf), nil
 }
 
-func (rc *signalingNopCloser) Close() error {
+func (rc *signalingNopWriteCloser) Close() error {
        close(rc.closed)
-       return nil
+       return rc.ReadCloser.Close()
 }
 
 // Test whether server properly closes connection when processing slow
 // requests
 func TestSlowRequest(t *testing.T) {
        pr, pw := io.Pipe()
-       go func(w io.Writer) {
+
+       writerDone := make(chan struct{})
+       go func() {
                for _, buf := range [][]byte{
                        streamBeginTypeStdin,
                        makeRecord(typeStdin, 1, nil),
                        pw.Write(buf)
                        time.Sleep(100 * time.Millisecond)
                }
-       }(pw)
-
-       rc := &signalingNopCloser{pr, make(chan bool)}
+               close(writerDone)
+       }()
+       defer func() {
+               <-writerDone
+               pw.Close()
+       }()
+
+       rc := &signalingNopWriteCloser{pr, make(chan bool)}
        handlerDone := make(chan bool)
 
        c := newChild(rc, http.HandlerFunc(func(
                w.WriteHeader(200)
                close(handlerDone)
        }))
-       go c.serve()
-       defer c.cleanUp()
-
-       timeout := time.After(2 * time.Second)
+       c.serve()
 
        <-handlerDone
-       select {
-       case <-rc.closed:
-               t.Log("FastCGI child closed connection")
-       case <-timeout:
-               t.Error("FastCGI child did not close socket after handling request")
-       }
+       <-rc.closed
+       t.Log("FastCGI child closed connection")
 }