| Index: mojo/public/go/application/describer.go
|
| diff --git a/mojo/public/go/application/describer.go b/mojo/public/go/application/describer.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bf4911bfb157bebd9d67a4ba05faa9fd8c59ca6c
|
| --- /dev/null
|
| +++ b/mojo/public/go/application/describer.go
|
| @@ -0,0 +1,103 @@
|
| +// 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 (
|
| + "fmt"
|
| + "log"
|
| +
|
| + "mojo/public/go/bindings"
|
| +
|
| + "mojo/public/interfaces/bindings/service_describer"
|
| +)
|
| +
|
| +// ServiceDescriberFactory implements ServiceFactory for ServiceDescriber.
|
| +// For cleanup purposes, it is also the implementation of a ServiceDescriber.
|
| +type ServiceDescriberFactory struct {
|
| + // mapping holds the map from interface names to ServiceDescription's.
|
| + mapping map[string]service_describer.ServiceDescription
|
| + // stubs stores the stubs for connections opened to this factory.
|
| + stubs []*bindings.Stub
|
| + // descriptionFactories maps interface names to ServiceDescriptionFactory's.
|
| + descriptionFactories map[string]*ServiceDescriptionFactory
|
| +}
|
| +
|
| +func newServiceDescriberFactory(mapping map[string]service_describer.ServiceDescription) *ServiceDescriberFactory {
|
| + return &ServiceDescriberFactory{
|
| + mapping: mapping,
|
| + descriptionFactories: make(map[string]*ServiceDescriptionFactory),
|
| + }
|
| +}
|
| +
|
| +func (sd *ServiceDescriberFactory) Create(request service_describer.ServiceDescriber_Request) {
|
| + stub := service_describer.NewServiceDescriberStub(request, sd, bindings.GetAsyncWaiter())
|
| + sd.stubs = append(sd.stubs, stub)
|
| + go func() {
|
| + for {
|
| + if err := stub.ServeRequest(); err != nil {
|
| + connectionError, ok := err.(*bindings.ConnectionError)
|
| + if !ok || !connectionError.Closed() {
|
| + log.Println(err)
|
| + }
|
| + break
|
| + }
|
| + }
|
| + }()
|
| +}
|
| +
|
| +func (sd *ServiceDescriberFactory) Close() {
|
| + for _, stub := range sd.stubs {
|
| + stub.Close()
|
| + }
|
| + for _, factory := range sd.descriptionFactories {
|
| + for _, stub := range factory.stubs {
|
| + stub.Close()
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Helper method for DescribeService
|
| +func (sd *ServiceDescriberFactory) getServiceDescriptionFactory(inInterfaceName string) *ServiceDescriptionFactory {
|
| + // Assumes the interface name is in the mapping.
|
| + if desc, ok := sd.descriptionFactories[inInterfaceName]; ok {
|
| + return desc
|
| + }
|
| + sd.descriptionFactories[inInterfaceName] = &ServiceDescriptionFactory{
|
| + impl: sd.mapping[inInterfaceName],
|
| + }
|
| + return sd.descriptionFactories[inInterfaceName]
|
| +}
|
| +
|
| +func (sd *ServiceDescriberFactory) DescribeService(inInterfaceName string, inDescriptionRequest service_describer.ServiceDescription_Request) (err error) {
|
| + if _, ok := sd.mapping[inInterfaceName]; ok {
|
| + sd.getServiceDescriptionFactory(inInterfaceName).Create(inDescriptionRequest)
|
| + return nil
|
| + }
|
| + return fmt.Errorf("The interface %s is unknown by this application", inInterfaceName)
|
| +}
|
| +
|
| +// ServiceDescriptionFactory implements ServiceFactory for ServiceDescription.
|
| +type ServiceDescriptionFactory struct {
|
| + // stubs stores the stubs for connections opened to this factory.
|
| + stubs []*bindings.Stub
|
| + // impl is the ServiceDescription implementation served by this factory.
|
| + impl service_describer.ServiceDescription
|
| +}
|
| +
|
| +func (serviceDescriptionFactory *ServiceDescriptionFactory) Create(request service_describer.ServiceDescription_Request) {
|
| + stub := service_describer.NewServiceDescriptionStub(request, serviceDescriptionFactory.impl, bindings.GetAsyncWaiter())
|
| + serviceDescriptionFactory.stubs = append(serviceDescriptionFactory.stubs, stub)
|
| + go func() {
|
| + for {
|
| + if err := stub.ServeRequest(); err != nil {
|
| + connectionError, ok := err.(*bindings.ConnectionError)
|
| + if !ok || !connectionError.Closed() {
|
| + log.Println(err)
|
| + }
|
| + break
|
| + }
|
| + }
|
| + }()
|
| +}
|
|
|