Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: mojo/public/go/bindings/connector.go

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/go/bindings/async_waiter.go ('k') | mojo/public/go/bindings/decoder.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package bindings
6
7 import (
8 "fmt"
9 "sync"
10
11 "mojo/public/go/system"
12 )
13
14 var errConnectionClosed = &ConnectionError{system.MOJO_RESULT_FAILED_PRECONDITIO N}
15
16 // ConnectionError represents a error caused by an operation on a message pipe.
17 type ConnectionError struct {
18 Result system.MojoResult
19 }
20
21 func (e *ConnectionError) Error() string {
22 return fmt.Sprintf("message pipe error: %v", e.Result)
23 }
24
25 // Closed returnes true iff the error was caused by an operation on a closed
26 // message pipe.
27 func (e *ConnectionError) Closed() bool {
28 return e.Result == system.MOJO_RESULT_FAILED_PRECONDITION
29 }
30
31 // Connector owns a message pipe handle. It can read and write messages
32 // from the message pipe waiting on it if necessary. The operation are
33 // thread-safe.
34 type Connector struct {
35 mu sync.RWMutex // protects pipe handle
36 pipe system.MessagePipeHandle
37
38 done chan struct{}
39 waitMutex sync.Mutex
40 waiter AsyncWaiter
41 waitChan chan WaitResponse
42 }
43
44 // NewStubConnector returns a new |Connector| instance that sends and
45 // receives messages from a provided message pipe handle.
46 func NewConnector(pipe system.MessagePipeHandle, waiter AsyncWaiter) *Connector {
47 return &Connector{
48 pipe: pipe,
49 waiter: waiter,
50 done: make(chan struct{}),
51 waitChan: make(chan WaitResponse, 1),
52 }
53 }
54
55 // ReadMessage reads a message from message pipe waiting on it if necessary.
56 func (c *Connector) ReadMessage() (*Message, error) {
57 // Make sure that only one goroutine at a time waits a the handle.
58 // We use separate lock so that we can send messages to the message pipe
59 // while waiting on the pipe.
60 //
61 // It is better to acquire this lock first so that a potential queue of
62 // readers will wait while closing the message pipe in case of Close()
63 // call.
64 c.waitMutex.Lock()
65 defer c.waitMutex.Unlock()
66 // Use read lock to use pipe handle without modifying it.
67 c.mu.RLock()
68 defer c.mu.RUnlock()
69
70 if !c.pipe.IsValid() {
71 return nil, errConnectionClosed
72 }
73 // Check if we already have a message.
74 result, bytes, handles := c.pipe.ReadMessage(system.MOJO_READ_MESSAGE_FL AG_NONE)
75 if result == system.MOJO_RESULT_SHOULD_WAIT {
76 waitId := c.waiter.AsyncWait(c.pipe, system.MOJO_HANDLE_SIGNAL_R EADABLE, c.waitChan)
77 select {
78 case <-c.waitChan:
79 result, bytes, handles = c.pipe.ReadMessage(system.MOJO_ READ_MESSAGE_FLAG_NONE)
80 if result != system.MOJO_RESULT_OK {
81 return nil, &ConnectionError{result}
82 }
83 case <-c.done:
84 c.waiter.CancelWait(waitId)
85 return nil, errConnectionClosed
86 }
87 } else if result != system.MOJO_RESULT_OK {
88 return nil, &ConnectionError{result}
89 }
90 return ParseMessage(bytes, handles)
91 }
92
93 // WriteMessage writes a message to the message pipe.
94 func (c *Connector) WriteMessage(message *Message) error {
95 // Use read lock to use pipe handle without modifying it.
96 c.mu.RLock()
97 defer c.mu.RUnlock()
98 if !c.pipe.IsValid() {
99 return errConnectionClosed
100 }
101 return WriteMessage(c.pipe, message)
102 }
103
104 // Close closes the message pipe aborting wait on the message pipe.
105 // Panics if you try to close the |Connector| more than once.
106 func (c *Connector) Close() {
107 // Stop waiting to acquire the lock.
108 close(c.done)
109 // Use write lock to modify the pipe handle.
110 c.mu.Lock()
111 c.pipe.Close()
112 c.mu.Unlock()
113 }
OLDNEW
« no previous file with comments | « mojo/public/go/bindings/async_waiter.go ('k') | mojo/public/go/bindings/decoder.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698