1 | // Copyright (c) 2018, 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 | #ifndef RUNTIME_VM_FINALIZABLE_DATA_H_ |
6 | #define RUNTIME_VM_FINALIZABLE_DATA_H_ |
7 | |
8 | #include "include/dart_api.h" |
9 | #include "platform/growable_array.h" |
10 | #include "vm/globals.h" |
11 | |
12 | namespace dart { |
13 | |
14 | struct FinalizableData { |
15 | void* data; |
16 | void* peer; |
17 | Dart_WeakPersistentHandleFinalizer callback; |
18 | Dart_WeakPersistentHandleFinalizer successful_write_callback; |
19 | }; |
20 | |
21 | class MessageFinalizableData { |
22 | public: |
23 | MessageFinalizableData() |
24 | : records_(0), get_position_(0), take_position_(0), external_size_(0) {} |
25 | |
26 | ~MessageFinalizableData() { |
27 | for (intptr_t i = take_position_; i < records_.length(); i++) { |
28 | records_[i].callback(nullptr, nullptr, records_[i].peer); |
29 | } |
30 | } |
31 | |
32 | /// If [successful_write_callback] is provided, it's invoked when message |
33 | /// was serialized successfully. |
34 | /// [callback] is invoked when serialization failed. |
35 | void Put( |
36 | intptr_t external_size, |
37 | void* data, |
38 | void* peer, |
39 | Dart_WeakPersistentHandleFinalizer callback, |
40 | Dart_WeakPersistentHandleFinalizer successful_write_callback = nullptr) { |
41 | FinalizableData finalizable_data; |
42 | finalizable_data.data = data; |
43 | finalizable_data.peer = peer; |
44 | finalizable_data.callback = callback; |
45 | finalizable_data.successful_write_callback = successful_write_callback; |
46 | records_.Add(finalizable_data); |
47 | external_size_ += external_size; |
48 | } |
49 | |
50 | // Retrieve the next FinalizableData, but still run its finalizer when |this| |
51 | // is destroyed. |
52 | FinalizableData Get() { |
53 | ASSERT(get_position_ < records_.length()); |
54 | return records_[get_position_++]; |
55 | } |
56 | |
57 | // Retrieve the next FinalizableData, and skip its finalizer when |this| is |
58 | // destroyed. |
59 | FinalizableData Take() { |
60 | ASSERT(take_position_ < records_.length()); |
61 | return records_[take_position_++]; |
62 | } |
63 | |
64 | void SerializationSucceeded() { |
65 | for (intptr_t i = 0; i < records_.length(); i++) { |
66 | if (records_[i].successful_write_callback != nullptr) { |
67 | records_[i].successful_write_callback(nullptr, nullptr, |
68 | records_[i].peer); |
69 | } |
70 | } |
71 | } |
72 | |
73 | void DropFinalizers() { |
74 | records_.Clear(); |
75 | get_position_ = 0; |
76 | take_position_ = 0; |
77 | external_size_ = 0; |
78 | } |
79 | |
80 | intptr_t external_size() const { return external_size_; } |
81 | |
82 | private: |
83 | MallocGrowableArray<FinalizableData> records_; |
84 | intptr_t get_position_; |
85 | intptr_t take_position_; |
86 | intptr_t external_size_; |
87 | |
88 | DISALLOW_COPY_AND_ASSIGN(MessageFinalizableData); |
89 | }; |
90 | |
91 | } // namespace dart |
92 | |
93 | #endif // RUNTIME_VM_FINALIZABLE_DATA_H_ |
94 | |