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 Completer _closeCompleter; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 endpoint.write( | 45 endpoint.write( |
46 response.buffer, response.buffer.lengthInBytes, response.handles); | 46 response.buffer, response.buffer.lengthInBytes, response.handles); |
47 // FailedPrecondition is only used to indicate that the other end of | 47 // FailedPrecondition is only used to indicate that the other end of |
48 // the pipe has been closed. We can ignore the close here and wait for | 48 // the pipe has been closed. We can ignore the close here and wait for |
49 // the PeerClosed signal on the event stream. | 49 // the PeerClosed signal on the event stream. |
50 assert(endpoint.status.isOk || endpoint.status.isFailedPrecondition); | 50 assert(endpoint.status.isOk || endpoint.status.isFailedPrecondition); |
51 if (_isClosing && (_outstandingResponseFutures == 0)) { | 51 if (_isClosing && (_outstandingResponseFutures == 0)) { |
52 // This was the final response future for which we needed to send | 52 // This was the final response future for which we needed to send |
53 // a response. It is safe to close. | 53 // a response. It is safe to close. |
54 super.close().then((_) { | 54 super.close().then((_) { |
55 _isClosing = false; | 55 if (_isClosing) { |
56 _closeCompleter.complete(null); | 56 _isClosing = false; |
57 _closeCompleter = null; | 57 _closeCompleter.complete(null); |
| 58 _closeCompleter = null; |
| 59 } |
58 }); | 60 }); |
59 } | 61 } |
60 } | 62 } |
61 }); | 63 }); |
62 } else if (_isClosing && (_outstandingResponseFutures == 0)) { | 64 } else if (_isClosing && (_outstandingResponseFutures == 0)) { |
63 // We are closing, there is no response to send for this message, and | 65 // We are closing, there is no response to send for this message, and |
64 // there are no outstanding response futures. Do the close now. | 66 // there are no outstanding response futures. Do the close now. |
65 super.close().then((_) { | 67 super.close().then((_) { |
66 _isClosing = false; | 68 if (_isClosing) { |
67 _closeCompleter.complete(null); | 69 _isClosing = false; |
68 _closeCompleter = null; | 70 _closeCompleter.complete(null); |
| 71 _closeCompleter = null; |
| 72 } |
69 }); | 73 }); |
70 } | 74 } |
71 } | 75 } |
72 | 76 |
73 void handleWrite() { | 77 void handleWrite() { |
74 throw 'Unexpected write signal in client.'; | 78 throw 'Unexpected write signal in client.'; |
75 } | 79 } |
76 | 80 |
77 // NB: |nodefer| should only be true when calling close() while handling an | 81 // NB: |immediate| should only be true when calling close() while handling an |
78 // exception thrown from handleRead(), e.g. when we receive a malformed | 82 // exception thrown from handleRead(), e.g. when we receive a malformed |
79 // message, or when we have received the PEER_CLOSED event. | 83 // message, or when we have received the PEER_CLOSED event. |
80 @override | 84 @override |
81 Future close({bool nodefer: false}) { | 85 Future close({bool immediate: false}) { |
82 if (isOpen && | 86 if (isOpen && |
83 !nodefer && | 87 !immediate && |
84 (isInHandler || (_outstandingResponseFutures > 0))) { | 88 (isInHandler || (_outstandingResponseFutures > 0))) { |
85 // Either close() is being called from within handleRead() or | 89 // Either close() is being called from within handleRead() or |
86 // handleWrite(), or close() is being called while there are outstanding | 90 // handleWrite(), or close() is being called while there are outstanding |
87 // response futures. Defer the actual close until all response futures | 91 // response futures. Defer the actual close until all response futures |
88 // have been resolved. | 92 // have been resolved. |
89 _isClosing = true; | 93 _isClosing = true; |
90 _closeCompleter = new Completer(); | 94 _closeCompleter = new Completer(); |
91 return _closeCompleter.future; | 95 return _closeCompleter.future; |
92 } else { | 96 } else { |
93 return super.close(nodefer: nodefer).then((_) { | 97 return super.close(immediate: immediate).then((_) { |
94 if (_isClosing) { | 98 if (_isClosing) { |
95 _isClosing = false; | 99 _isClosing = false; |
96 _closeCompleter.complete(null); | 100 _closeCompleter.complete(null); |
97 _closeCompleter = null; | 101 _closeCompleter = null; |
98 } | 102 } |
99 }); | 103 }); |
100 } | 104 } |
101 } | 105 } |
102 | 106 |
103 Message buildResponse(Struct response, int name) { | 107 Message buildResponse(Struct response, int name) { |
104 var header = new MessageHeader(name); | 108 var header = new MessageHeader(name); |
105 return response.serializeWithHeader(header); | 109 return response.serializeWithHeader(header); |
106 } | 110 } |
107 | 111 |
108 Message buildResponseWithId(Struct response, int name, int id, int flags) { | 112 Message buildResponseWithId(Struct response, int name, int id, int flags) { |
109 var header = new MessageHeader.withRequestId(name, flags, id); | 113 var header = new MessageHeader.withRequestId(name, flags, id); |
110 return response.serializeWithHeader(header); | 114 return response.serializeWithHeader(header); |
111 } | 115 } |
112 | 116 |
113 String toString() { | 117 String toString() { |
114 var superString = super.toString(); | 118 var superString = super.toString(); |
115 return "Stub(${superString})"; | 119 return "Stub(${superString})"; |
116 } | 120 } |
117 } | 121 } |
OLD | NEW |