OLD | NEW |
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 abstract class Stub extends core.MojoEventStreamListener { | 7 abstract class Stub extends core.MojoEventStreamListener { |
8 int _outstandingResponseFutures = 0; | 8 int _outstandingResponseFutures = 0; |
9 bool _isClosing = false; | 9 bool _isClosing = false; |
| 10 Completer _closeCompleter; |
10 | 11 |
11 Stub.fromEndpoint(core.MojoMessagePipeEndpoint endpoint) | 12 Stub.fromEndpoint(core.MojoMessagePipeEndpoint endpoint) |
12 : super.fromEndpoint(endpoint); | 13 : super.fromEndpoint(endpoint); |
13 | 14 |
14 Stub.fromHandle(core.MojoHandle handle) : super.fromHandle(handle); | 15 Stub.fromHandle(core.MojoHandle handle) : super.fromHandle(handle); |
15 | 16 |
16 Stub.unbound() : super.unbound(); | 17 Stub.unbound() : super.unbound(); |
17 | 18 |
18 Future<Message> handleMessage(ServiceMessage message); | 19 Future<Message> handleMessage(ServiceMessage message); |
19 | 20 |
(...skipping 24 matching lines...) Expand all Loading... |
44 endpoint.write( | 45 endpoint.write( |
45 response.buffer, response.buffer.lengthInBytes, response.handles); | 46 response.buffer, response.buffer.lengthInBytes, response.handles); |
46 if (!endpoint.status.isOk) { | 47 if (!endpoint.status.isOk) { |
47 throw 'message pipe write failed: ${endpoint.status}'; | 48 throw 'message pipe write failed: ${endpoint.status}'; |
48 } | 49 } |
49 if (_isClosing && (_outstandingResponseFutures == 0)) { | 50 if (_isClosing && (_outstandingResponseFutures == 0)) { |
50 // This was the final response future for which we needed to send | 51 // This was the final response future for which we needed to send |
51 // a response. It is safe to close. | 52 // a response. It is safe to close. |
52 super.close(); | 53 super.close(); |
53 _isClosing = false; | 54 _isClosing = false; |
| 55 _closeCompleter.complete(null); |
| 56 _closeCompleter = null; |
54 } | 57 } |
55 } | 58 } |
56 }); | 59 }); |
57 } else if (_isClosing && (_outstandingResponseFutures == 0)) { | 60 } else if (_isClosing && (_outstandingResponseFutures == 0)) { |
58 // We are closing, there is no response to send for this message, and | 61 // We are closing, there is no response to send for this message, and |
59 // there are no outstanding response futures. Do the close now. | 62 // there are no outstanding response futures. Do the close now. |
60 super.close(); | 63 super.close(); |
61 _isClosing = false; | 64 _isClosing = false; |
| 65 _closeCompleter.complete(null); |
| 66 _closeCompleter = null; |
62 } | 67 } |
63 } | 68 } |
64 | 69 |
65 void handleWrite() { | 70 void handleWrite() { |
66 throw 'Unexpected write signal in client.'; | 71 throw 'Unexpected write signal in client.'; |
67 } | 72 } |
68 | 73 |
69 // NB: |nodefer| should only be true when calling close() while handling an | 74 // NB: |nodefer| should only be true when calling close() while handling an |
70 // exception thrown from handleRead(), e.g. when we receive a malformed | 75 // exception thrown from handleRead(), e.g. when we receive a malformed |
71 // message. | 76 // message. |
72 void close({bool nodefer: false}) { | 77 Future close({bool nodefer: false}) { |
73 if (isOpen && | 78 if (isOpen && |
74 !nodefer && | 79 !nodefer && |
75 (isInHandler || (_outstandingResponseFutures > 0))) { | 80 (isInHandler || (_outstandingResponseFutures > 0))) { |
76 // Either close() is being called from within handleRead() or | 81 // Either close() is being called from within handleRead() or |
77 // handleWrite(), or close() is being called while there are outstanding | 82 // handleWrite(), or close() is being called while there are outstanding |
78 // response futures. Defer the actual close until all response futures | 83 // response futures. Defer the actual close until all response futures |
79 // have been resolved. | 84 // have been resolved. |
80 _isClosing = true; | 85 _isClosing = true; |
| 86 _closeCompleter = new Completer(); |
| 87 return _closeCompleter.future; |
81 } else { | 88 } else { |
82 super.close(); | 89 return super.close(); |
83 } | 90 } |
84 } | 91 } |
85 | 92 |
86 Message buildResponse(Struct response, int name) { | 93 Message buildResponse(Struct response, int name) { |
87 var header = new MessageHeader(name); | 94 var header = new MessageHeader(name); |
88 return response.serializeWithHeader(header); | 95 return response.serializeWithHeader(header); |
89 } | 96 } |
90 | 97 |
91 Message buildResponseWithId(Struct response, int name, int id, int flags) { | 98 Message buildResponseWithId(Struct response, int name, int id, int flags) { |
92 var header = new MessageHeader.withRequestId(name, flags, id); | 99 var header = new MessageHeader.withRequestId(name, flags, id); |
93 return response.serializeWithHeader(header); | 100 return response.serializeWithHeader(header); |
94 } | 101 } |
95 | 102 |
96 String toString() { | 103 String toString() { |
97 var superString = super.toString(); | 104 var superString = super.toString(); |
98 return "Stub(${superString})"; | 105 return "Stub(${superString})"; |
99 } | 106 } |
100 } | 107 } |
OLD | NEW |