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

Side by Side Diff: mojo/dart/packages/mojo/lib/src/stub.dart

Issue 2006093002: Dart: Futures -> Callbacks. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Merge Created 4 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 part of bindings; 5 part of bindings;
6 6
7 /// Generated StubControl classes implement this interface. 7 /// Generated StubControl classes implement this interface.
8 /// StubControl objects are accessible through the [ctrl] field on Stubs. 8 /// StubControl objects are accessible through the [ctrl] field on Stubs.
9 abstract class StubControl<T> implements StubMessageHandler { 9 abstract class StubControl<T> implements StubMessageHandler {
10 // TODO(zra): This is only used by ApplicationConnection.requestService(), so 10 // TODO(zra): This is only used by ApplicationConnection.requestService(), so
(...skipping 25 matching lines...) Expand all
36 /// ctrl.impl. If a Mojo interface has a method 'impl', its name will be 36 /// ctrl.impl. If a Mojo interface has a method 'impl', its name will be
37 /// mangled to be 'impl_'. 37 /// mangled to be 'impl_'.
38 T get impl => ctrl.impl; 38 T get impl => ctrl.impl;
39 set impl(T impl) { 39 set impl(T impl) {
40 ctrl.impl = impl; 40 ctrl.impl = impl;
41 } 41 }
42 } 42 }
43 43
44 abstract class StubMessageHandler extends core.MojoEventHandler 44 abstract class StubMessageHandler extends core.MojoEventHandler
45 implements MojoInterfaceControl { 45 implements MojoInterfaceControl {
46 int _outstandingResponseFutures = 0;
47 bool _isClosing = false;
48 Completer _closeCompleter;
49
50 StubMessageHandler.fromEndpoint(core.MojoMessagePipeEndpoint endpoint, 46 StubMessageHandler.fromEndpoint(core.MojoMessagePipeEndpoint endpoint,
51 {bool autoBegin: true}) 47 {bool autoBegin: true})
52 : super.fromEndpoint(endpoint, autoBegin: autoBegin); 48 : super.fromEndpoint(endpoint, autoBegin: autoBegin);
53 49
54 StubMessageHandler.fromHandle(core.MojoHandle handle, {bool autoBegin: true}) 50 StubMessageHandler.fromHandle(core.MojoHandle handle, {bool autoBegin: true})
55 : super.fromHandle(handle, autoBegin: autoBegin); 51 : super.fromHandle(handle, autoBegin: autoBegin);
56 52
57 StubMessageHandler.unbound() : super.unbound(); 53 StubMessageHandler.unbound() : super.unbound();
58 54
59 /// Generated StubControl classes implement this method to route messages to 55 /// Generated StubControl classes implement this method to route messages to
60 /// the correct implementation method. 56 /// the correct implementation method.
61 dynamic handleMessage(ServiceMessage message); 57 void handleMessage(ServiceMessage message);
62 58
63 /// Generated StubControl classes implement this getter to return the version 59 /// Generated StubControl classes implement this getter to return the version
64 /// of the mojom interface for which the bindings are generated. 60 /// of the mojom interface for which the bindings are generated.
65 int get version; 61 int get version;
66 62
67 @override 63 @override
68 void handleRead() { 64 void handleRead() {
69 var result = endpoint.queryAndRead(); 65 var result = endpoint.queryAndRead();
70 if ((result.data == null) || (result.dataLength == 0)) { 66 if ((result.data == null) || (result.dataLength == 0)) {
71 throw new MojoCodecError('Unexpected empty message or error: $result'); 67 throw new MojoCodecError('Unexpected empty message or error: $result');
72 } 68 }
73 69
74 // Prepare the response.
75 var message;
76 var response;
77 try { 70 try {
78 message = new ServiceMessage.fromMessage(new Message(result.data, 71 var message = new ServiceMessage.fromMessage(new Message(result.data,
79 result.handles, result.dataLength, result.handlesLength)); 72 result.handles, result.dataLength, result.handlesLength));
80 response = _isClosing ? null : handleMessage(message); 73 handleMessage(message);
81 } catch (e) { 74 } catch (e) {
82 if (result.handles != null) { 75 if (result.handles != null) {
83 result.handles.forEach((h) => h.close()); 76 result.handles.forEach((h) => h.close());
84 } 77 }
85 rethrow; 78 rethrow;
86 } 79 }
87
88 // If there's a response, send it.
89 if (response != null) {
90 if (response is Future) {
91 _outstandingResponseFutures++;
92 response.then((response) {
93 _outstandingResponseFutures--;
94 return response;
95 }).then(_sendResponse);
96 } else {
97 _sendResponse(response);
98 }
99 } else if (_isClosing && (_outstandingResponseFutures == 0)) {
100 // We are closing, there is no response to send for this message, and
101 // there are no outstanding response futures. Do the close now.
102 super.close().then((_) {
103 if (_isClosing) {
104 _isClosing = false;
105 _closeCompleter.complete(null);
106 _closeCompleter = null;
107 }
108 });
109 }
110 } 80 }
111 81
112 @override 82 @override
113 void handleWrite() { 83 void handleWrite() {
114 throw 'Unexpected write signal in client.'; 84 throw 'Unexpected write signal in client.';
115 } 85 }
116 86
117 // NB: |immediate| should only be true when calling close() while handling an 87 /// Called by generated handleMessage functions in implementations.
118 // exception thrown from handleRead(), e.g. when we receive a malformed 88 void sendResponse(Message response) {
119 // message, or when we have received the PEER_CLOSED event. 89 if (isOpen) {
120 @override 90 endpoint.write(
121 Future close({bool immediate: false}) { 91 response.buffer, response.buffer.lengthInBytes, response.handles);
122 if (isOpen && 92 // FailedPrecondition is only used to indicate that the other end of
123 !immediate && 93 // the pipe has been closed. We can ignore the close here and wait for
124 !isPeerClosed && 94 // the PeerClosed signal on the event stream.
125 (isInHandler || (_outstandingResponseFutures > 0))) { 95 assert((endpoint.status == core.MojoResult.kOk) ||
126 // Either close() is being called from within handleRead() or 96 (endpoint.status == core.MojoResult.kFailedPrecondition));
127 // handleWrite(), or close() is being called while there are outstanding
128 // response futures. Defer the actual close until all response futures
129 // have been resolved.
130 _isClosing = true;
131 _closeCompleter = new Completer();
132 return _closeCompleter.future;
133 } else {
134 return super.close(immediate: immediate).then((_) {
135 if (_isClosing) {
136 _isClosing = false;
137 _closeCompleter.complete(null);
138 _closeCompleter = null;
139 }
140 });
141 } 97 }
142 } 98 }
143 99
144 Message buildResponse(Struct response, int name) { 100 Message buildResponse(Struct response, int name) {
145 var header = new MessageHeader(name); 101 var header = new MessageHeader(name);
146 return response.serializeWithHeader(header); 102 return response.serializeWithHeader(header);
147 } 103 }
148 104
149 Message buildResponseWithId(Struct response, int name, int id, int flags) { 105 Message buildResponseWithId(Struct response, int name, int id, int flags) {
150 var header = new MessageHeader.withRequestId(name, flags, id); 106 var header = new MessageHeader.withRequestId(name, flags, id);
151 return response.serializeWithHeader(header); 107 return response.serializeWithHeader(header);
152 } 108 }
153 109
154 @override 110 @override
155 String toString() { 111 String toString() {
156 var superString = super.toString(); 112 var superString = super.toString();
157 return "StubMessageHandler(${superString})"; 113 return "StubMessageHandler(${superString})";
158 } 114 }
159 115
160 /// Returns a service description, which exposes the mojom type information 116 /// Returns a service description, which exposes the mojom type information
161 /// of the service being stubbed. 117 /// of the service being stubbed.
162 /// Note: The description is null or incomplete if type info is unavailable. 118 /// Note: The description is null or incomplete if type info is unavailable.
163 service_describer.ServiceDescription get description => null; 119 service_describer.ServiceDescription get description => null;
164
165 void _sendResponse(Message response) {
166 if (isOpen) {
167 endpoint.write(
168 response.buffer, response.buffer.lengthInBytes, response.handles);
169 // FailedPrecondition is only used to indicate that the other end of
170 // the pipe has been closed. We can ignore the close here and wait for
171 // the PeerClosed signal on the event stream.
172 assert((endpoint.status == core.MojoResult.kOk) ||
173 (endpoint.status == core.MojoResult.kFailedPrecondition));
174 if (_isClosing && (_outstandingResponseFutures == 0)) {
175 // This was the final response future for which we needed to send
176 // a response. It is safe to close.
177 super.close().then((_) {
178 if (_isClosing) {
179 _isClosing = false;
180 _closeCompleter.complete(null);
181 _closeCompleter = null;
182 }
183 });
184 }
185 }
186 }
187 } 120 }
OLDNEW
« no previous file with comments | « mojo/dart/packages/mojo/lib/src/proxy.dart ('k') | mojo/dart/packages/mojo_services/lib/activity/activity.mojom.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698