Index: third_party/mojo/src/mojo/public/go/bindings/stub.go |
diff --git a/third_party/mojo/src/mojo/public/go/bindings/stub.go b/third_party/mojo/src/mojo/public/go/bindings/stub.go |
index b2b3120a08c0fe68c979b9657d4e95b399f9a755..c7ca09f51e6d757fb8fec4bf87369cdd51753d2e 100644 |
--- a/third_party/mojo/src/mojo/public/go/bindings/stub.go |
+++ b/third_party/mojo/src/mojo/public/go/bindings/stub.go |
@@ -4,6 +4,10 @@ |
package bindings |
+import ( |
+ "sync" |
+) |
+ |
// MessageReceiver can receive |Message| objects. |
type MessageReceiver interface { |
// Accept receives a |Message|. Returns a error if the message was not |
@@ -16,6 +20,8 @@ type MessageReceiver interface { |
// implementation. If the method returns result, the stub serializes the |
// response and sends it back. |
type Stub struct { |
+ // Makes sure that connector is closed only once. |
+ closeOnce sync.Once |
connector *Connector |
receiver MessageReceiver |
} |
@@ -23,19 +29,27 @@ type Stub struct { |
// NewStub returns a new Stub instance using provided |Connector| to send and |
// receive messages. Incoming messages are handled by the provided |receiver|. |
func NewStub(connector *Connector, receiver MessageReceiver) *Stub { |
- return &Stub{connector, receiver} |
+ return &Stub{ |
+ connector: connector, |
+ receiver: receiver, |
+ } |
} |
// ServeRequest synchronously serves one request from the message pipe: the |
// |Stub| waits on its underlying message pipe for a message and handles it. |
// Can be called from multiple goroutines. Each calling goroutine will receive |
-// a different message or an error. |
+// a different message or an error. Closes itself in case of error. |
func (s *Stub) ServeRequest() error { |
message, err := s.connector.ReadMessage() |
if err != nil { |
+ s.Close() |
return err |
} |
- return s.receiver.Accept(message) |
+ err = s.receiver.Accept(message) |
+ if err != nil { |
+ s.Close() |
+ } |
+ return err |
} |
// Close immediately closes the |Stub| and its underlying message pipe. If the |
@@ -43,5 +57,7 @@ func (s *Stub) ServeRequest() error { |
// All goroutines trying to serve will start returning errors as the underlying |
// message pipe becomes invalid. |
func (s *Stub) Close() { |
- s.connector.Close() |
+ s.closeOnce.Do(func() { |
+ s.connector.Close() |
+ }) |
} |