Dave
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
package main
import (
"errors"
"fmt"
"math/rand"
)
type Future interface {
Result() error
}
type TaskResult chan error
func (ch TaskResult) Result() (err error) {
defer func() {
if err != nil {
ch <- err
}
}()
return <-ch
}
func RunTask() Future {
ch := make(chan error, 1)
go func() {
if rand.Intn(100) > 50 {
ch <- nil
return
}
ch <- errors.New("FAILED")
}()
return TaskResult(ch)
}
func main() {
for i := 0; i < 10; i++ {
fmt.Println(RunTask().Result())
package main
import (
"errors"
"fmt"
"math/rand"
)
type Future interface {
Result() error
}
type TaskResult chan error
func (ch TaskResult) Result() (err error) {
defer func() {
ch <- err
--
Peter's solution, a little simpler:
http://play.golang.org/p/qUDPHEWQwG
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
Sorry, I think this solution is not correct because closing fu.ch does
not correctly publish fu.err.
On Fri, Apr 19, 2013 at 10:46 PM, Dave Cheney <da...@cheney.net> wrote:Sorry, I think this solution is not correct because closing fu.ch does
not correctly publish fu.err.How about this:if close is happening after the assignment to fu.err, it will be a violation ofdefer semantics. (let's ignore the case when the provided work function itselfpanics)
On Friday, April 19, 2013 11:51:55 AM UTC-4, minux wrote:Still incorrect, now I see the problem. Although this assignment must happen beforethe close of channel, other goroutine might not see this order as happen-beforeorder is not total.
You are correct that the order is not total; unsynchronized goroutines have no hb relationships between them.But the order _is_ transitive: if A hb B and B hb C then A hb C. Otherwise I am my own grandpa, end of the world, cats and dogs living together...
Concretely:fu.err = f() happens before close(fu.ch),<-fu.ch happens before return fu.errand you can see where this is going...
Or put it another way, in theory, Go channel operations are not memory barriersaccording the Go memory model document.
I guess they must be.
You are confusing the notion of observer. From the memory model:
"The Go memory model specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine."There is only one read (return fu.err) and it is guaranteed to observe the write (fu.err = f()) because of the transitivity of hb-relationships that I described.
You are confusing the notion of observer. From the memory model:
"The Go memory model specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine."There is only one read (return fu.err) and it is guaranteed to observe the write (fu.err = f()) because of the transitivity of hb-relationships that I described.ok, let's try another simpler example.a = 1; b = 2; // goroutine 1, assignment to a happens before assignment to b, this is the usual order.from another goroutine, it might find b = 2 but a != 1. This is the first example in golang.org/ref/mem.
This demonstrate that the observer plays an important role in hb relationships, and after switchingobserver, a hb relation might not hold.
the essential question is still: whether channel communication operations also act as memory barriers.i don't see any memory barriers in the implementation of channel (in fact, the 3 memory barrierinstructions are not even implemented for ARM).