示例#1
0
// CreateMessagePipeForInterface creates a message pipe with interface request
// on one end and interface pointer on the other end. The interface request
// should be attached to appropriate mojo interface implementation and
// the interface pointer should be attached to mojo interface proxy.
func CreateMessagePipeForMojoInterface() (InterfaceRequest, InterfacePointer) {
	r, h0, h1 := system.GetCore().CreateMessagePipe(nil)
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create a message pipe: %v", r))
	}
	return InterfaceRequest{MessagePipeHandleOwner{h0}}, InterfacePointer{MessagePipeHandleOwner{h1}}
}
// newAsyncWaiter creates an asyncWaiterImpl and starts its worker goroutine.
func newAsyncWaiter() *asyncWaiterImpl {
	result, h0, h1 := system.GetCore().CreateMessagePipe(nil)
	if result != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create message pipe %v", result))
	}
	waitChan := make(chan waitRequest, 10)
	cancelChan := make(chan AsyncWaitId, 10)
	isNotified := new(int32)
	worker := &asyncWaiterWorker{
		[]system.Handle{h1},
		[]system.MojoHandleSignals{system.MOJO_HANDLE_SIGNAL_READABLE},
		[]AsyncWaitId{0},
		[]chan<- WaitResponse{make(chan WaitResponse)},
		isNotified,
		waitChan,
		cancelChan,
		0,
	}
	runtime.SetFinalizer(worker, finalizeWorker)
	go worker.runLoop()
	waiter := &asyncWaiterImpl{
		wakingHandle:     h0,
		isWorkerNotified: isNotified,
		waitChan:         waitChan,
		cancelChan:       cancelChan,
	}
	runtime.SetFinalizer(waiter, finalizeAsyncWaiter)
	return waiter
}
// runLoop run loop of the asyncWaiterWorker. Blocks on |WaitMany()|. If the
// wait is interrupted by waking handle (index 0) then it means that the worker
// was woken by waiterImpl, so the worker processes incoming requests from
// waiterImpl; otherwise responses to corresponding wait request.
func (w *asyncWaiterWorker) runLoop() {
	for {
		result, index, states := system.GetCore().WaitMany(w.handles, w.signals, system.MOJO_DEADLINE_INDEFINITE)
		// Set flag to 0, so that the next incoming request to
		// waiterImpl would explicitly wake worker by sending a message
		// to waking message pipe.
		atomic.StoreInt32(w.isNotified, 0)
		if index == -1 {
			panic(fmt.Sprintf("error waiting on handles: %v", result))
			break
		}
		// Zero index means that the worker was signaled by asyncWaiterImpl.
		if index == 0 {
			if result != system.MOJO_RESULT_OK {
				panic(fmt.Sprintf("error waiting on waking handle: %v", result))
			}
			w.handles[0].(system.MessagePipeHandle).ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
			w.processIncomingRequests()
		} else if result != system.MOJO_RESULT_OK {
			w.sendWaitResponseAndRemove(index, result, system.MojoHandleSignalsState{})
		} else {
			w.respondToSatisfiedWaits(states)
		}
	}
}
示例#4
0
// Implements net.Listener.
func (l *MojoListener) Accept() (net.Conn, error) {
	r, sendProducer, sendConsumer := system.GetCore().CreateDataPipe(nil)
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create data pipe: %v", r))
	}
	r, receiveProducer, receiveConsumer := system.GetCore().CreateDataPipe(nil)
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create data pipe: %v", r))
	}
	request, pointer := tcp_connected_socket.CreateMessagePipeForTcpConnectedSocket()
	networkError, remoteAddress, err := l.serverSocket.Accept(sendConsumer, receiveProducer, request)
	if err != nil {
		return nil, err
	}
	if networkError.Code != 0 {
		return nil, fmt.Errorf("%s", *networkError.Description)
	}

	var addr net.Addr
	if remoteAddress.Ipv4 != nil {
		addr = &net.TCPAddr{
			IP:   remoteAddress.Ipv4.Addr[:4],
			Port: int(remoteAddress.Ipv4.Port),
		}
	} else {
		addr = &net.TCPAddr{
			IP:   remoteAddress.Ipv6.Addr[:16],
			Port: int(remoteAddress.Ipv6.Port),
		}
	}
	return &MojoConnection{
		sendProducer,
		receiveConsumer,
		pointer.PassMessagePipe(),
		l.Addr(),
		addr,
	}, nil
}
示例#5
0
func (u *mupdate) GetAttachment(name string) (system.ConsumerHandle, error) {
	r, producer, consumer := system.GetCore().CreateDataPipe(nil)
	if r != system.MOJO_RESULT_OK {
		return nil, fmt.Errorf("can't create data pipe: %v", r)
	}
	go func() {
		defer producer.Close()

		dataOrErr := <-u.u.Attachment(u.ctx, name)
		if dataOrErr.Error != nil {
			u.ctx.Error(dataOrErr.Error)
		} else {
			producer.WriteData([]byte(dataOrErr.Data), system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
		}
	}()
	return consumer, nil
}
// Run binds your mojo application to provided message pipe handle and runs it
// until the application is terminated.
func Run(delegate Delegate, applicationRequest system.MojoHandle) {
	messagePipe := system.GetCore().AcquireNativeHandle(applicationRequest).ToMessagePipeHandle()
	appRequest := application.Application_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
	impl := &ApplicationImpl{
		delegate: delegate,
	}
	stub := application.NewApplicationStub(appRequest, impl, bindings.GetAsyncWaiter())
	impl.runner = stub
	for {
		if err := stub.ServeRequest(); err != nil {
			connectionError, ok := err.(*bindings.ConnectionError)
			if !ok || !connectionError.Closed() {
				log.Println(err)
			}
			impl.RequestQuit()
			break
		}
	}
}
示例#7
0
func (h *HttpHandler) HandleRequest(request http_request.HttpRequest) (http_response.HttpResponse, error) {
	resp := "Hello, Go http handler!"
	r, producer, consumer := system.GetCore().CreateDataPipe(&system.DataPipeOptions{
		system.MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
		1,
		uint32(len(resp)),
	})
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create data pipe: %v", r))
	}

	producer.WriteData([]byte(resp), system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
	producer.Close()
	return http_response.HttpResponse{
		200,
		&consumer,
		int64(len(resp)),
		"text/html; charset=utf-8",
		nil,
	}, nil
}
示例#8
0
func init() {
	embedder.InitializeMojoEmbedder()
	core = system.GetCore()
	waiter = bindings.GetAsyncWaiter()
}