| Index: third_party/mojo/src/mojo/public/go/application/connection.go
|
| diff --git a/third_party/mojo/src/mojo/public/go/application/connection.go b/third_party/mojo/src/mojo/public/go/application/connection.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5b2c62998e2f52e1e121fbbafe5efdf07ad22afc
|
| --- /dev/null
|
| +++ b/third_party/mojo/src/mojo/public/go/application/connection.go
|
| @@ -0,0 +1,174 @@
|
| +// 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 application
|
| +
|
| +import (
|
| + "log"
|
| +
|
| + "mojo/public/go/bindings"
|
| + "mojo/public/go/system"
|
| +
|
| + sp "mojo/public/interfaces/application/service_provider"
|
| +)
|
| +
|
| +type connectionInfo struct {
|
| + requestorURL string
|
| + connectionURL string
|
| +}
|
| +
|
| +// RequestorURL returns the URL of application that established the connection.
|
| +func (c *connectionInfo) RequestorURL() string {
|
| + return c.requestorURL
|
| +}
|
| +
|
| +// ConnectionURL returns the URL that was used by the source application to
|
| +// establish a connection to the destination application.
|
| +func (c *connectionInfo) ConnectionURL() string {
|
| + return c.connectionURL
|
| +}
|
| +
|
| +// ServiceRequest is an interface request for a specified mojo service.
|
| +type ServiceRequest interface {
|
| + // Name returns the name of requested mojo service.
|
| + Name() string
|
| +
|
| + // PassMessagePipe passes ownership of the underlying message pipe
|
| + // handle to the newly created handle object, invalidating the
|
| + // underlying handle object in the process.
|
| + PassMessagePipe() system.MessagePipeHandle
|
| +}
|
| +
|
| +// ServiceFactory provides implementation of a mojo service.
|
| +type ServiceFactory interface {
|
| + // Name returns the name of provided mojo service.
|
| + Name() string
|
| +
|
| + // Create binds an implementation of mojo service to the provided
|
| + // message pipe and runs it.
|
| + Create(pipe system.MessagePipeHandle)
|
| +}
|
| +
|
| +// Connection represents a connection to another application. An instance of
|
| +// this struct is passed to Delegate's AcceptConnection() function each time a
|
| +// connection is made to this application.
|
| +type Connection struct {
|
| + connectionInfo
|
| + // Request for local services. Is valid until ProvideServices is called.
|
| + servicesRequest *sp.ServiceProviderRequest
|
| + // Indicates that ProvideServices function was already called.
|
| + servicesProvided bool
|
| + localServices *bindings.Stub
|
| + outgoingConnection *OutgoingConnection
|
| + isClosed bool
|
| +}
|
| +
|
| +func newConnection(requestorURL string, services *sp.ServiceProviderRequest, exposedServices *sp.ServiceProviderPointer, resolvedURL string) *Connection {
|
| + info := connectionInfo{
|
| + requestorURL,
|
| + resolvedURL,
|
| + }
|
| + var remoteServices *sp.ServiceProviderProxy
|
| + if exposedServices != nil {
|
| + remoteServices = sp.NewServiceProviderProxy(*exposedServices, bindings.GetAsyncWaiter())
|
| + }
|
| + return &Connection{
|
| + connectionInfo: info,
|
| + servicesRequest: services,
|
| + outgoingConnection: &OutgoingConnection{
|
| + info,
|
| + remoteServices,
|
| + },
|
| + }
|
| +}
|
| +
|
| +// ProvideServices starts a service provider on a separate goroutine that
|
| +// provides given services to the remote application. Returns a pointer to
|
| +// outgoing connection that can be used to connect to services provided by
|
| +// remote application.
|
| +// Panics if called more than once.
|
| +func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnection {
|
| + if c.servicesProvided {
|
| + panic("ProvideServices can be called only once")
|
| + }
|
| + c.servicesProvided = true
|
| + if c.servicesRequest == nil {
|
| + return c.outgoingConnection
|
| + }
|
| + if len(services) == 0 {
|
| + c.servicesRequest.PassMessagePipe().Close()
|
| + return c.outgoingConnection
|
| + }
|
| +
|
| + provider := &serviceProviderImpl{
|
| + make(map[string]ServiceFactory),
|
| + }
|
| + for _, service := range services {
|
| + provider.AddService(service)
|
| + }
|
| + c.localServices = sp.NewServiceProviderStub(*c.servicesRequest, provider, bindings.GetAsyncWaiter())
|
| + go func() {
|
| + for {
|
| + if err := c.localServices.ServeRequest(); err != nil {
|
| + // TODO(rogulenko): don't log in case message pipe was closed
|
| + log.Println(err)
|
| + break
|
| + }
|
| + }
|
| + }()
|
| + return c.outgoingConnection
|
| +}
|
| +
|
| +// Close closes both incoming and outgoing parts of the connection.
|
| +func (c *Connection) Close() {
|
| + if c.servicesRequest != nil {
|
| + c.servicesRequest.Close()
|
| + }
|
| + if c.localServices != nil {
|
| + c.localServices.Close()
|
| + }
|
| + if c.outgoingConnection.remoteServices != nil {
|
| + c.outgoingConnection.remoteServices.Close_proxy()
|
| + }
|
| + c.isClosed = true
|
| +}
|
| +
|
| +// OutgoingConnection represents outgoing part of connection to another
|
| +// application. In order to close it close the |Connection| object that returned
|
| +// this |OutgoingConnection|.
|
| +type OutgoingConnection struct {
|
| + connectionInfo
|
| + remoteServices *sp.ServiceProviderProxy
|
| +}
|
| +
|
| +// ConnectToService asks remote application to provide a service through the
|
| +// message pipe endpoint supplied by the caller.
|
| +func (c *OutgoingConnection) ConnectToService(request ServiceRequest) {
|
| + pipe := request.PassMessagePipe()
|
| + if c.remoteServices == nil {
|
| + pipe.Close()
|
| + return
|
| + }
|
| + c.remoteServices.ConnectToService(request.Name(), pipe)
|
| +}
|
| +
|
| +// serviceProviderImpl is an implementation of mojo ServiceProvider interface.
|
| +type serviceProviderImpl struct {
|
| + factories map[string]ServiceFactory
|
| +}
|
| +
|
| +// Mojo ServiceProvider implementation.
|
| +func (sp *serviceProviderImpl) ConnectToService(name string, messagePipe system.MessagePipeHandle) error {
|
| + factory, ok := sp.factories[name]
|
| + if !ok {
|
| + messagePipe.Close()
|
| + return nil
|
| + }
|
| + factory.Create(messagePipe)
|
| + return nil
|
| +}
|
| +
|
| +func (sp *serviceProviderImpl) AddService(factory ServiceFactory) {
|
| + sp.factories[factory.Name()] = factory
|
| +}
|
|
|