| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Dart core library. | 5 // Dart core library. |
| 6 | 6 |
| 7 class PromiseImpl<T> implements Promise<T> { | 7 class PromiseImpl<T> implements Promise<T> { |
| 8 | 8 |
| 9 // Enumeration of possible states: | 9 // Enumeration of possible states: |
| 10 static final int CREATED = 0; | 10 static final int CREATED = 0; |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 addCompleteHandler((val) { | 255 addCompleteHandler((val) { |
| 256 promises.forEach((promise) { | 256 promises.forEach((promise) { |
| 257 if (!promise.isDone()) { | 257 if (!promise.isDone()) { |
| 258 promise.cancel(); | 258 promise.cancel(); |
| 259 } | 259 } |
| 260 }); | 260 }); |
| 261 }); | 261 }); |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 | 264 |
| 265 class ProxyBase { | 265 // For now, extend Promise<bool> rather than either |
| 266 // a) create a new base, Completable, for Promise and Proxy, or |
| 267 // b) extend Promise<SendPort> which would expose the port. |
| 268 class ProxyBase extends PromiseImpl<bool> { |
| 266 | 269 |
| 267 ProxyBase.forPort(SendPort port) { | 270 ProxyBase.forPort(SendPort port) { |
| 268 _promise = new Promise<SendPort>(); | 271 _promise = new Promise<SendPort>(); |
| 269 _promise.complete(port); | 272 _promise.complete(port); |
| 273 complete(true); |
| 270 } | 274 } |
| 271 | 275 |
| 272 // Construct a proxy for a message reply; see the [Proxy.forReply] | 276 // Construct a proxy for a message reply; see the [Proxy.forReply] |
| 273 // documentation for more details. | 277 // documentation for more details. |
| 274 ProxyBase.forReply(Promise<SendPort> port) { | 278 ProxyBase.forReply(Promise<SendPort> port) { |
| 275 _promise = port; | 279 _promise = port; |
| 280 port.addCompleteHandler((_) => complete(true)); |
| 276 } | 281 } |
| 277 | 282 |
| 278 // Note that comparing proxies or using them in maps is illegal | 283 // Note that comparing proxies or using them in maps or sets is |
| 279 // until they complete. | 284 // illegal until they complete. |
| 280 bool operator ==(var other) { | 285 bool operator ==(var other) { |
| 281 return (other is ProxyBase) && _promise.value == other._promise.value; | 286 return (other is ProxyBase) && _promise.value == other._promise.value; |
| 282 } | 287 } |
| 283 | 288 |
| 284 int hashCode() => _promise.value.hashCode(); | 289 int hashCode() => _promise.value.hashCode(); |
| 285 | 290 |
| 286 // TODO: consider making this extend Promise<SendPort> instead? | |
| 287 void addCompleteHandler(void completeHandler()) { | |
| 288 _promise.addCompleteHandler((_) => completeHandler()); | |
| 289 } | |
| 290 | |
| 291 static ReceivePort register(Dispatcher dispatcher) { | 291 static ReceivePort register(Dispatcher dispatcher) { |
| 292 if (_dispatchers === null) { | 292 if (_dispatchers === null) { |
| 293 _dispatchers = new Map<SendPort, Dispatcher>(); | 293 _dispatchers = new Map<SendPort, Dispatcher>(); |
| 294 } | 294 } |
| 295 ReceivePort result = new ReceivePort(); | 295 ReceivePort result = new ReceivePort(); |
| 296 _dispatchers[result.toSendPort()] = dispatcher; | 296 _dispatchers[result.toSendPort()] = dispatcher; |
| 297 return result; | 297 return result; |
| 298 } | 298 } |
| 299 | 299 |
| 300 get local() { | 300 get local() { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 325 result.complete(message[0]); | 325 result.complete(message[0]); |
| 326 }); | 326 }); |
| 327 return result; | 327 return result; |
| 328 }); | 328 }); |
| 329 } | 329 } |
| 330 | 330 |
| 331 // Marshal the [message] and pass it to the [process] callback | 331 // Marshal the [message] and pass it to the [process] callback |
| 332 // function. Any promises are converted to a port which expects to | 332 // function. Any promises are converted to a port which expects to |
| 333 // receive a port from the other side down which the remote promise | 333 // receive a port from the other side down which the remote promise |
| 334 // can be completed by sending the promise's completion value. | 334 // can be completed by sending the promise's completion value. |
| 335 Promise _marshal(List message, process(List marshalled)) { | 335 Promise _marshal(List message, process(List marshalled)) { |
| 336 return _promise.then((SendPort port) { | 336 return _promise.then((SendPort port) { |
| 337 List marshalled = new List(message.length); | 337 List marshalled = new List(message.length); |
| 338 | 338 |
| 339 for (int i = 0; i < marshalled.length; i++) { | 339 for (int i = 0; i < marshalled.length; i++) { |
| 340 var entry = message[i]; | 340 var entry = message[i]; |
| 341 if (entry is Proxy) { | 341 if (entry is Proxy) { |
| 342 entry = entry._promise; | 342 entry = entry._promise; |
| 343 } | 343 } |
| 344 // Obviously this will be true if [entry] was a Proxy. | 344 // Obviously this will be true if [entry] was a Proxy. |
| 345 if (entry is Promise) { | 345 if (entry is Promise) { |
| 346 // Note that we could optimise this by just sending the value | 346 // Note that we could optimise this by just sending the value |
| 347 // if the promise is already complete. Let's get this working | 347 // if the promise is already complete. Let's get this working |
| 348 // first! | 348 // first! |
| 349 | 349 |
| 350 // This port will receive a SendPort that can be used to | 350 // This port will receive a SendPort that can be used to |
| 351 // signal completion of this promise to the corresponding | 351 // signal completion of this promise to the corresponding |
| 352 // promise that the other end has created. | 352 // promise that the other end has created. |
| 353 ReceivePort receiveCompleter = new ReceivePort.singleShot(); | 353 ReceivePort receiveCompleter = new ReceivePort.singleShot(); |
| 354 marshalled[i] = receiveCompleter.toSendPort(); | 354 marshalled[i] = receiveCompleter.toSendPort(); |
| 355 Promise<SendPort> completer = new Promise<SendPort>(); | 355 Promise<SendPort> completer = new Promise<SendPort>(); |
| 356 receiveCompleter.receive((var msg, SendPort replyPort) { | 356 receiveCompleter.receive((var msg, SendPort replyPort) { |
| 357 completer.complete(msg[0]); | 357 completer.complete(msg[0]); |
| 358 }); | 358 }); |
| 359 entry.addCompleteHandler((value) { | 359 entry.addCompleteHandler((value) { |
| 360 completer.addCompleteHandler((SendPort port) { | 360 completer.addCompleteHandler((SendPort port) { |
| 361 port.send([value], null); | 361 _marshal([value], (List message) => port.send(message, null)); |
| 362 }); | 362 }); |
| 363 }); | 363 }); |
| 364 } else { | 364 } else { |
| 365 // FIXME(kasperl, benl): this should probably be a copy? | 365 // FIXME(kasperl, benl): this should probably be a copy? |
| 366 marshalled[i] = entry; | 366 marshalled[i] = entry; |
| 367 } | 367 } |
| 368 if (marshalled[i] is ReceivePort) { | 368 if (marshalled[i] is ReceivePort) { |
| 369 throw new Exception("Despite the documentation, you cannot send a Rece
ivePort"); | 369 throw new Exception("Despite the documentation, you cannot send a Rece
ivePort"); |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 return process(marshalled); | 372 return process(marshalled); |
| 373 }).flatten(); | 373 }).flatten(); |
| 374 } | 374 } |
| 375 | 375 |
| 376 Promise<SendPort> _promise; | 376 Promise<SendPort> _promise; |
| 377 static Map<SendPort, Dispatcher> _dispatchers; | 377 static Map<SendPort, Dispatcher> _dispatchers; |
| 378 | 378 |
| 379 } | 379 } |
| OLD | NEW |