@@ -25,6 +25,18 @@ pub struct StorageHandle<Db> {
25
25
phantom : PhantomData < fn ( ) -> Db > ,
26
26
}
27
27
28
+ impl < Db > Clone for StorageHandle < Db > {
29
+ fn clone ( & self ) -> Self {
30
+ * self . coordinate . clones . lock ( ) += 1 ;
31
+
32
+ Self {
33
+ zalsa_impl : self . zalsa_impl . clone ( ) ,
34
+ coordinate : CoordinateDrop ( Arc :: clone ( & self . coordinate ) ) ,
35
+ phantom : PhantomData ,
36
+ }
37
+ }
38
+ }
39
+
28
40
impl < Db : Database > Default for StorageHandle < Db > {
29
41
fn default ( ) -> Self {
30
42
Self {
@@ -40,15 +52,8 @@ impl<Db: Database> Default for StorageHandle<Db> {
40
52
41
53
impl < Db > StorageHandle < Db > {
42
54
pub fn into_storage ( self ) -> Storage < Db > {
43
- let StorageHandle {
44
- zalsa_impl,
45
- coordinate,
46
- phantom,
47
- } = self ;
48
55
Storage {
49
- zalsa_impl,
50
- coordinate,
51
- phantom,
56
+ handle : self ,
52
57
zalsa_local : ZalsaLocal :: new ( ) ,
53
58
}
54
59
}
@@ -68,20 +73,10 @@ pub unsafe trait HasStorage: Database + Clone + Sized {
68
73
69
74
/// Concrete implementation of the [`Database`] trait with local state that can be used to drive computations.
70
75
pub struct Storage < Db > {
71
- // Note: Drop order is important, zalsa_impl needs to drop before coordinate
72
- /// Reference to the database.
73
- zalsa_impl : Arc < Zalsa > ,
74
-
75
- // Note: Drop order is important, coordinate needs to drop after zalsa_impl
76
- /// Coordination data for cancellation of other handles when `zalsa_mut` is called.
77
- /// This could be stored in Zalsa but it makes things marginally cleaner to keep it separate.
78
- coordinate : CoordinateDrop ,
76
+ handle : StorageHandle < Db > ,
79
77
80
78
/// Per-thread state
81
79
zalsa_local : zalsa_local:: ZalsaLocal ,
82
-
83
- /// We store references to `Db`
84
- phantom : PhantomData < fn ( ) -> Db > ,
85
80
}
86
81
87
82
struct Coordinate {
@@ -98,13 +93,8 @@ impl RefUnwindSafe for Coordinate {}
98
93
impl < Db : Database > Default for Storage < Db > {
99
94
fn default ( ) -> Self {
100
95
Self {
101
- zalsa_impl : Arc :: new ( Zalsa :: new :: < Db > ( ) ) ,
102
- coordinate : CoordinateDrop ( Arc :: new ( Coordinate {
103
- clones : Mutex :: new ( 1 ) ,
104
- cvar : Default :: default ( ) ,
105
- } ) ) ,
96
+ handle : StorageHandle :: default ( ) ,
106
97
zalsa_local : ZalsaLocal :: new ( ) ,
107
- phantom : PhantomData ,
108
98
}
109
99
}
110
100
}
@@ -114,16 +104,10 @@ impl<Db: Database> Storage<Db> {
114
104
/// and [`std::panic::UnwindSafe`].
115
105
pub fn into_zalsa_handle ( self ) -> StorageHandle < Db > {
116
106
let Storage {
117
- zalsa_impl,
118
- coordinate,
119
- phantom,
107
+ handle,
120
108
zalsa_local : _,
121
109
} = self ;
122
- StorageHandle {
123
- zalsa_impl,
124
- coordinate,
125
- phantom,
126
- }
110
+ handle
127
111
}
128
112
129
113
pub fn debug_input_entries < T > ( & self ) -> impl Iterator < Item = & input:: Value < T > >
@@ -171,7 +155,7 @@ impl<Db: Database> Storage<Db> {
171
155
/// possible as `zalsa_impl` only becomes
172
156
/// `None` once we are in the `Drop` impl.
173
157
fn zalsa_impl ( & self ) -> & Arc < Zalsa > {
174
- & self . zalsa_impl
158
+ & self . handle . zalsa_impl
175
159
}
176
160
177
161
// ANCHOR: cancel_other_workers
@@ -181,29 +165,29 @@ impl<Db: Database> Storage<Db> {
181
165
/// This could deadlock if there is a single worker with two handles to the
182
166
/// same database!
183
167
fn cancel_others ( & self , db : & Db ) {
184
- self . zalsa_impl . set_cancellation_flag ( ) ;
168
+ self . handle . zalsa_impl . set_cancellation_flag ( ) ;
185
169
186
170
db. salsa_event ( & || Event :: new ( EventKind :: DidSetCancellationFlag ) ) ;
187
171
188
- let mut clones = self . coordinate . clones . lock ( ) ;
172
+ let mut clones = self . handle . coordinate . clones . lock ( ) ;
189
173
while * clones != 1 {
190
- self . coordinate . cvar . wait ( & mut clones) ;
174
+ self . handle . coordinate . cvar . wait ( & mut clones) ;
191
175
}
192
176
}
193
177
// ANCHOR_END: cancel_other_workers
194
178
}
195
179
196
180
unsafe impl < T : HasStorage > ZalsaDatabase for T {
197
181
fn zalsa ( & self ) -> & Zalsa {
198
- & self . storage ( ) . zalsa_impl
182
+ & self . storage ( ) . handle . zalsa_impl
199
183
}
200
184
201
185
fn zalsa_mut ( & mut self ) -> & mut Zalsa {
202
186
self . storage ( ) . cancel_others ( self ) ;
203
187
204
188
let storage = self . storage_mut ( ) ;
205
189
// The ref count on the `Arc` should now be 1
206
- let zalsa_mut = Arc :: get_mut ( & mut storage. zalsa_impl ) . unwrap ( ) ;
190
+ let zalsa_mut = Arc :: get_mut ( & mut storage. handle . zalsa_impl ) . unwrap ( ) ;
207
191
zalsa_mut. new_revision ( ) ;
208
192
zalsa_mut
209
193
}
@@ -219,13 +203,9 @@ unsafe impl<T: HasStorage> ZalsaDatabase for T {
219
203
220
204
impl < Db : Database > Clone for Storage < Db > {
221
205
fn clone ( & self ) -> Self {
222
- * self . coordinate . clones . lock ( ) += 1 ;
223
-
224
206
Self {
225
- zalsa_impl : self . zalsa_impl . clone ( ) ,
226
- coordinate : CoordinateDrop ( Arc :: clone ( & self . coordinate ) ) ,
207
+ handle : self . handle . clone ( ) ,
227
208
zalsa_local : ZalsaLocal :: new ( ) ,
228
- phantom : PhantomData ,
229
209
}
230
210
}
231
211
}
0 commit comments