| Index: third_party/mojo/src/mojo/public/go/bindings/router.go
|
| diff --git a/third_party/mojo/src/mojo/public/go/bindings/router.go b/third_party/mojo/src/mojo/public/go/bindings/router.go
|
| deleted file mode 100644
|
| index 1e8daba6e36eef78ca4fbcd226854b02499d1b21..0000000000000000000000000000000000000000
|
| --- a/third_party/mojo/src/mojo/public/go/bindings/router.go
|
| +++ /dev/null
|
| @@ -1,228 +0,0 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -package bindings
|
| -
|
| -import (
|
| - "fmt"
|
| - "sync"
|
| -
|
| - "mojo/public/go/system"
|
| -)
|
| -
|
| -// MessageReadResult contains information returned after reading and parsing
|
| -// a message: a non-nil error of a valid message.
|
| -type MessageReadResult struct {
|
| - Message *Message
|
| - Error error
|
| -}
|
| -
|
| -// routeRequest is a request sent from Router to routerWorker.
|
| -type routeRequest struct {
|
| - // The outgoing message with non-zero request id.
|
| - message *Message
|
| - // The channel to send respond for the message.
|
| - responseChan chan<- MessageReadResult
|
| -}
|
| -
|
| -// routerWorker sends messages that require a response and and routes responses
|
| -// to appropriate receivers. The work is done on a separate go routine.
|
| -type routerWorker struct {
|
| - // The message pipe handle to send requests and receive responses.
|
| - handle system.MessagePipeHandle
|
| - // Map from request id to response channel.
|
| - responders map[uint64]chan<- MessageReadResult
|
| - // The channel of incoming requests that require responses.
|
| - requestChan <-chan routeRequest
|
| - // The channel that indicates that the worker should terminate.
|
| - done <-chan struct{}
|
| - // Implementation of async waiter.
|
| - waiter AsyncWaiter
|
| - waitChan chan WaitResponse
|
| - waitId AsyncWaitId
|
| -}
|
| -
|
| -// readOutstandingMessages reads and dispatches available messages in the
|
| -// message pipe until the messages is empty or there are no waiting responders.
|
| -// If the worker is currently waiting on the message pipe, returns immediately
|
| -// without an error.
|
| -func (w *routerWorker) readAndDispatchOutstandingMessages() error {
|
| - if w.waitId != 0 {
|
| - // Still waiting for a new message in the message pipe.
|
| - return nil
|
| - }
|
| - for len(w.responders) > 0 {
|
| - result, bytes, handles := w.handle.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
|
| - if result == system.MOJO_RESULT_SHOULD_WAIT {
|
| - w.waitId = w.waiter.AsyncWait(w.handle, system.MOJO_HANDLE_SIGNAL_READABLE, w.waitChan)
|
| - return nil
|
| - }
|
| - if result != system.MOJO_RESULT_OK {
|
| - return &ConnectionError{result}
|
| - }
|
| - message, err := ParseMessage(bytes, handles)
|
| - if err != nil {
|
| - return err
|
| - }
|
| - id := message.Header.RequestId
|
| - w.responders[id] <- MessageReadResult{message, nil}
|
| - delete(w.responders, id)
|
| - }
|
| - return nil
|
| -}
|
| -
|
| -func (w *routerWorker) cancelIfWaiting() {
|
| - if w.waitId != 0 {
|
| - w.waiter.CancelWait(w.waitId)
|
| - w.waitId = 0
|
| - }
|
| -}
|
| -
|
| -// runLoop is the main run loop of the worker. It processes incoming requests
|
| -// from Router and waits on a message pipe for new messages.
|
| -// Returns an error describing the cause of stopping.
|
| -func (w *routerWorker) runLoop() error {
|
| - for {
|
| - select {
|
| - case waitResponse := <-w.waitChan:
|
| - w.waitId = 0
|
| - if waitResponse.Result != system.MOJO_RESULT_OK {
|
| - return &ConnectionError{waitResponse.Result}
|
| - }
|
| - case request := <-w.requestChan:
|
| - if err := WriteMessage(w.handle, request.message); err != nil {
|
| - return err
|
| - }
|
| - if request.responseChan != nil {
|
| - w.responders[request.message.Header.RequestId] = request.responseChan
|
| - }
|
| - case <-w.done:
|
| - return errConnectionClosed
|
| - }
|
| - // Returns immediately without an error if still waiting for
|
| - // a new message.
|
| - if err := w.readAndDispatchOutstandingMessages(); err != nil {
|
| - return err
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Router sends messages to a message pipe and routes responses back to senders
|
| -// of messages with non-zero request ids. The caller should issue unique request
|
| -// ids for each message given to the router.
|
| -type Router struct {
|
| - // Mutex protecting requestChan from new requests in case the router is
|
| - // closed and the handle.
|
| - mu sync.Mutex
|
| - // The message pipe handle to send requests and receive responses.
|
| - handle system.MessagePipeHandle
|
| - // Channel to communicate with worker.
|
| - requestChan chan<- routeRequest
|
| -
|
| - // Makes sure that the done channel is closed once.
|
| - closeOnce sync.Once
|
| - // Channel to stop the worker.
|
| - done chan<- struct{}
|
| -}
|
| -
|
| -// NewRouter returns a new Router instance that sends and receives messages
|
| -// from a provided message pipe handle.
|
| -func NewRouter(handle system.MessagePipeHandle, waiter AsyncWaiter) *Router {
|
| - requestChan := make(chan routeRequest, 10)
|
| - doneChan := make(chan struct{})
|
| - router := &Router{
|
| - handle: handle,
|
| - requestChan: requestChan,
|
| - done: doneChan,
|
| - }
|
| - router.runWorker(&routerWorker{
|
| - handle,
|
| - make(map[uint64]chan<- MessageReadResult),
|
| - requestChan,
|
| - doneChan,
|
| - waiter,
|
| - make(chan WaitResponse, 1),
|
| - 0,
|
| - })
|
| - return router
|
| -}
|
| -
|
| -// Close closes the router and the underlying message pipe. All new incoming
|
| -// requests are returned with an error.
|
| -func (r *Router) Close() {
|
| - r.closeOnce.Do(func() {
|
| - close(r.done)
|
| - })
|
| -}
|
| -
|
| -// Accept sends a message to the message pipe. The message should have a
|
| -// zero request id in header.
|
| -func (r *Router) Accept(message *Message) error {
|
| - if message.Header.RequestId != 0 {
|
| - return fmt.Errorf("message header should have a zero request ID")
|
| - }
|
| - r.mu.Lock()
|
| - defer r.mu.Unlock()
|
| - if !r.handle.IsValid() {
|
| - return errConnectionClosed
|
| - }
|
| - r.requestChan <- routeRequest{message, nil}
|
| - return nil
|
| -}
|
| -
|
| -func (r *Router) runWorker(worker *routerWorker) {
|
| - // Run worker on a separate go routine.
|
| - go func() {
|
| - // Get the reason why the worker stopped. The error means that
|
| - // either the router is closed or there was an error reading
|
| - // or writing to a message pipe. In both cases it will be
|
| - // the reason why we can't process any more requests.
|
| - err := worker.runLoop()
|
| - worker.cancelIfWaiting()
|
| - // Respond to all pending requests.
|
| - for _, responseChan := range worker.responders {
|
| - responseChan <- MessageReadResult{nil, err}
|
| - }
|
| - // Respond to incoming requests until we make sure that all
|
| - // new requests return with an error before sending request
|
| - // to responseChan.
|
| - go func() {
|
| - for responder := range worker.requestChan {
|
| - responder.responseChan <- MessageReadResult{nil, err}
|
| - }
|
| - }()
|
| - r.mu.Lock()
|
| - r.handle.Close()
|
| - // If we acquire the lock then no other go routine is waiting
|
| - // to write to responseChan. All go routines that acquire the
|
| - // lock after us will return before sending to responseChan as
|
| - // the underlying handle is invalid (already closed).
|
| - // We can safely close the requestChan.
|
| - close(r.requestChan)
|
| - r.mu.Unlock()
|
| - }()
|
| -}
|
| -
|
| -// AcceptWithResponse sends a message to the message pipe and returns a channel
|
| -// that will stream the result of reading corresponding response. The message
|
| -// should have a non-zero request id in header. It is responsibility of the
|
| -// caller to issue unique request ids for all given messages.
|
| -func (r *Router) AcceptWithResponse(message *Message) <-chan MessageReadResult {
|
| - responseChan := make(chan MessageReadResult, 1)
|
| - if message.Header.RequestId == 0 {
|
| - responseChan <- MessageReadResult{nil, fmt.Errorf("message header should have a request ID")}
|
| - return responseChan
|
| - }
|
| - r.mu.Lock()
|
| - defer r.mu.Unlock()
|
| - // Return an error before sending a request to requestChan if the router
|
| - // is closed so that we can safely close responseChan once we close the
|
| - // router.
|
| - if !r.handle.IsValid() {
|
| - responseChan <- MessageReadResult{nil, errConnectionClosed}
|
| - return responseChan
|
| - }
|
| - r.requestChan <- routeRequest{message, responseChan}
|
| - return responseChan
|
| -}
|
|
|