title: Is this Go code thread safe or do I need a mutex?
body: <p>Suppose I have the following function, <code>doWork</code>, that starts some work in a goroutine and returns a <code>Result</code> to check for completion and error:  </p>
  
  <pre><code>func doWork() *Result {
      r := Result{doneCh: make(chan struct{})}
      go func() {
          var err error
          defer func() {
              r.err = err
              close(r.doneCh)
          }()
          // do some work
      }()
      return &amp;r
  }
  </code></pre>
  
  <p>where <code>Result</code> is the following struct:</p>
  
  <pre><code>type Result struct {
      doneCh      chan struct{}
      err         error
  }
  // doneCh returns a closed chan when the work is done.
  func (r *Result) Done() &lt;-chan struct{} {
      return r.doneCh
  }
  // Err returns a non-nil err if the work failed.
  // Don't call Err until Done returns a closed chan.
  func (r *Result) Err() error {
      return r.err
  }
  </code></pre>
  
  <p>is this code thread safe if I set <code>err</code> before closing <code>doneCh</code>:</p>
  
  <pre><code>defer func() {
      r.err = err
      close(r.doneCh)
  }()
  </code></pre>
  
  <p>or is the compiler free to order the <code>r.err = err</code> and <code>close(r.doneCh)</code> instructions as it likes, in which case I'd need a mutex to prevent concurrent read/writes on error.</p>