OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library utils; | |
6 | |
7 import 'dart-ext:dart_archive'; | |
8 import 'dart:isolate'; | |
9 import 'archive.dart' as archive; | |
10 | |
11 /** The cache of the port used to communicate with the C extension. */ | |
12 SendPort _port; | |
13 | |
14 /** The port used to communicate with the C extension. */ | |
15 SendPort get servicePort { | |
16 if (_port == null) _port = _newServicePort(); | |
17 return _port; | |
18 } | |
19 | |
20 /** Creates a new port to communicate with the C extension. */ | |
21 SendPort _newServicePort() native "Archive_ServicePort"; | |
22 | |
23 /** | |
24 * Send a message to the C extension. | |
25 * | |
26 * [requestType] is the specific request id to send. [id] is the id of the | |
27 * archive; it may be null for requests that don't operate on a specific | |
28 * archive. [args] are arguments that will be passed on to the extension. They | |
29 * should all be C-safe. | |
30 * | |
31 * Returns a future that completes with the C extension's reply. | |
32 */ | |
33 Future call(int requestType, [int id, List args]) { | |
34 var fullArgs = [requestType, id]; | |
35 if (args != null) fullArgs.addAll(args); | |
36 return servicePort.call(listForC(fullArgs)).then((response) { | |
37 var success = response[0]; | |
38 var errno = response[1]; | |
39 var message = response[2]; | |
40 | |
41 if (!success) throw new ArchiveException(message, errno); | |
42 return message; | |
43 }); | |
44 } | |
45 | |
46 /** Converts [input] to a fixed-length list which C can understand. */ | |
47 List listForC(List input) { | |
48 var list = new List.fixedLength(input.length); | |
49 list.setRange(0, input.length, input); | |
50 return list; | |
51 } | |
52 | |
53 /** Converts [input] to a [Uint8List] that C can process easily. */ | |
54 Uint8List bytesForC(List<int> input) { | |
55 var list = new Uint8List(input.length); | |
56 list.setRange(0, input.length, input); | |
57 return list; | |
58 } | |
59 | |
60 /** | |
61 * Attaches [callback] as a finalizer for [object]. After [object] has been | |
62 * garbage collected, [callback] will be called and passed [peer] as an | |
63 * argument. | |
64 * | |
65 * Neither [callback] nor [peer] should contain any references to [object]; | |
66 * otherwise, [object] will never be collected and [callback] will never be | |
67 * called. | |
68 */ | |
69 void attachFinalizer(object, void callback(peer), [peer]) {} | |
70 | |
71 // TODO(nweiz): re-enable this once issue 4378 is fixed. | |
72 // void attachFinalizer(object, void callback(peer), [peer]) | |
73 // native "Archive_AttachFinalizer"; | |
74 | |
75 /** | |
76 * A reference to a single value. | |
77 * | |
78 * This is primarily meant to be used when a finalizer needs to refer to a field | |
79 * on the object being finalized that may be set to null during the lifetime of | |
80 * the object. Since the object itself has been garbage collected once the | |
81 * finalizer runs, it needs a second-order reference to check if the field is | |
82 * null. | |
83 */ | |
84 class Reference<E> { | |
85 E value; | |
86 Reference(this.value); | |
87 } | |
88 | |
89 /** | |
90 * Returns a [Future] that completes immediately upon hitting the event loop. | |
91 */ | |
92 Future async() { | |
93 var completer = new Completer(); | |
94 new Timer(0, (_) => completer.complete(null)); | |
95 return completer.future; | |
96 } | |
97 | |
98 /** An error raised by the archive library. */ | |
99 class ArchiveException implements archive.ArchiveException { | |
100 /** A description of the error that occurred. */ | |
101 final String message; | |
102 | |
103 /** The error code for the error, or null. */ | |
104 final int errno; | |
105 | |
106 ArchiveException(this.message, [this.errno]); | |
107 | |
108 String toString() { | |
109 if (errno == null) return "Archive error: $message"; | |
110 return "Archive error $errno: $message"; | |
111 } | |
112 } | |
OLD | NEW |