@@ -170,6 +170,86 @@ impl BorrowFlags {
170
170
unsafe fn get ( & self ) -> & mut HashMap < usize , isize > {
171
171
( * self . 0 . get ( ) ) . get_or_insert_with ( HashMap :: new)
172
172
}
173
+
174
+ fn acquire < T , D > ( & self , array : & PyArray < T , D > ) -> Result < ( ) , BorrowError > {
175
+ let address = base_address ( array) ;
176
+
177
+ // SAFETY: Access to `&PyArray<T, D>` implies holding the GIL
178
+ // and we are not calling into user code which might re-enter this function.
179
+ let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
180
+
181
+ match borrow_flags. entry ( address) {
182
+ Entry :: Occupied ( entry) => {
183
+ let readers = entry. into_mut ( ) ;
184
+
185
+ let new_readers = readers. wrapping_add ( 1 ) ;
186
+
187
+ if new_readers <= 0 {
188
+ cold ( ) ;
189
+ return Err ( BorrowError :: AlreadyBorrowed ) ;
190
+ }
191
+
192
+ * readers = new_readers;
193
+ }
194
+ Entry :: Vacant ( entry) => {
195
+ entry. insert ( 1 ) ;
196
+ }
197
+ }
198
+
199
+ Ok ( ( ) )
200
+ }
201
+
202
+ fn release < T , D > ( & self , array : & PyArray < T , D > ) {
203
+ let address = base_address ( array) ;
204
+
205
+ // SAFETY: Access to `&PyArray<T, D>` implies holding the GIL
206
+ // and we are not calling into user code which might re-enter this function.
207
+ let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
208
+
209
+ let readers = borrow_flags. get_mut ( & address) . unwrap ( ) ;
210
+
211
+ * readers -= 1 ;
212
+
213
+ if * readers == 0 {
214
+ borrow_flags. remove ( & address) . unwrap ( ) ;
215
+ }
216
+ }
217
+
218
+ fn acquire_mut < T , D > ( & self , array : & PyArray < T , D > ) -> Result < ( ) , BorrowError > {
219
+ let address = base_address ( array) ;
220
+
221
+ // SAFETY: Access to `&PyArray<T, D>` implies holding the GIL
222
+ // and we are not calling into user code which might re-enter this function.
223
+ let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
224
+
225
+ match borrow_flags. entry ( address) {
226
+ Entry :: Occupied ( entry) => {
227
+ let writers = entry. into_mut ( ) ;
228
+
229
+ if * writers != 0 {
230
+ cold ( ) ;
231
+ return Err ( BorrowError :: AlreadyBorrowed ) ;
232
+ }
233
+
234
+ * writers = -1 ;
235
+ }
236
+ Entry :: Vacant ( entry) => {
237
+ entry. insert ( -1 ) ;
238
+ }
239
+ }
240
+
241
+ Ok ( ( ) )
242
+ }
243
+
244
+ fn release_mut < T , D > ( & self , array : & PyArray < T , D > ) {
245
+ let address = base_address ( array) ;
246
+
247
+ // SAFETY: Access to `&PyArray<T, D>` implies holding the GIL
248
+ // and we are not calling into user code which might re-enter this function.
249
+ let borrow_flags = unsafe { self . get ( ) } ;
250
+
251
+ borrow_flags. remove ( & address) . unwrap ( ) ;
252
+ }
173
253
}
174
254
175
255
static BORROW_FLAGS : BorrowFlags = BorrowFlags :: new ( ) ;
@@ -224,29 +304,7 @@ where
224
304
D : Dimension ,
225
305
{
226
306
pub ( crate ) fn try_new ( array : & ' py PyArray < T , D > ) -> Result < Self , BorrowError > {
227
- let address = base_address ( array) ;
228
-
229
- // SAFETY: Access to a `&'py PyArray<T, D>` implies holding the GIL
230
- // and we are not calling into user code which might re-enter this function.
231
- let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
232
-
233
- match borrow_flags. entry ( address) {
234
- Entry :: Occupied ( entry) => {
235
- let readers = entry. into_mut ( ) ;
236
-
237
- let new_readers = readers. wrapping_add ( 1 ) ;
238
-
239
- if new_readers <= 0 {
240
- cold ( ) ;
241
- return Err ( BorrowError :: AlreadyBorrowed ) ;
242
- }
243
-
244
- * readers = new_readers;
245
- }
246
- Entry :: Vacant ( entry) => {
247
- entry. insert ( 1 ) ;
248
- }
249
- }
307
+ BORROW_FLAGS . acquire ( array) ?;
250
308
251
309
Ok ( Self ( array) )
252
310
}
@@ -287,19 +345,7 @@ where
287
345
288
346
impl < ' a , T , D > Drop for PyReadonlyArray < ' a , T , D > {
289
347
fn drop ( & mut self ) {
290
- let address = base_address ( self . 0 ) ;
291
-
292
- // SAFETY: Access to a `&'py PyArray<T, D>` implies holding the GIL
293
- // and we are not calling into user code which might re-enter this function.
294
- let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
295
-
296
- let readers = borrow_flags. get_mut ( & address) . unwrap ( ) ;
297
-
298
- * readers -= 1 ;
299
-
300
- if * readers == 0 {
301
- borrow_flags. remove ( & address) . unwrap ( ) ;
302
- }
348
+ BORROW_FLAGS . release ( self . 0 ) ;
303
349
}
304
350
}
305
351
@@ -358,27 +404,7 @@ where
358
404
return Err ( BorrowError :: NotWriteable ) ;
359
405
}
360
406
361
- let address = base_address ( array) ;
362
-
363
- // SAFETY: Access to a `&'py PyArray<T, D>` implies holding the GIL
364
- // and we are not calling into user code which might re-enter this function.
365
- let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
366
-
367
- match borrow_flags. entry ( address) {
368
- Entry :: Occupied ( entry) => {
369
- let writers = entry. into_mut ( ) ;
370
-
371
- if * writers != 0 {
372
- cold ( ) ;
373
- return Err ( BorrowError :: AlreadyBorrowed ) ;
374
- }
375
-
376
- * writers = -1 ;
377
- }
378
- Entry :: Vacant ( entry) => {
379
- entry. insert ( -1 ) ;
380
- }
381
- }
407
+ BORROW_FLAGS . acquire_mut ( array) ?;
382
408
383
409
Ok ( Self ( array) )
384
410
}
@@ -407,15 +433,44 @@ where
407
433
}
408
434
}
409
435
410
- impl < ' a , T , D > Drop for PyReadwriteArray < ' a , T , D > {
411
- fn drop ( & mut self ) {
412
- let address = base_address ( self . 0 ) ;
436
+ impl < ' py , T > PyReadwriteArray < ' py , T , Ix1 >
437
+ where
438
+ T : Element ,
439
+ {
440
+ /// Extends or truncates the length of a one-dimensional array.
441
+ ///
442
+ /// # Example
443
+ ///
444
+ /// ```
445
+ /// use numpy::PyArray;
446
+ /// use pyo3::Python;
447
+ ///
448
+ /// Python::with_gil(|py| {
449
+ /// let pyarray = PyArray::arange(py, 0, 10, 1);
450
+ /// assert_eq!(pyarray.len(), 10);
451
+ ///
452
+ /// let pyarray = pyarray.readwrite();
453
+ /// let pyarray = pyarray.resize(100).unwrap();
454
+ /// assert_eq!(pyarray.len(), 100);
455
+ /// });
456
+ /// ```
457
+ pub fn resize ( self , new_elems : usize ) -> PyResult < Self > {
458
+ BORROW_FLAGS . release_mut ( self . 0 ) ;
459
+
460
+ // SAFETY: Ownership of `self` proves exclusive access to the interior of the array.
461
+ unsafe {
462
+ self . 0 . resize ( new_elems) ?;
463
+ }
413
464
414
- // SAFETY: Access to a `&'py PyArray<T, D>` implies holding the GIL
415
- // and we are not calling into user code which might re-enter this function.
416
- let borrow_flags = unsafe { BORROW_FLAGS . get ( ) } ;
465
+ BORROW_FLAGS . acquire_mut ( self . 0 ) ?;
417
466
418
- borrow_flags. remove ( & address) . unwrap ( ) ;
467
+ Ok ( self )
468
+ }
469
+ }
470
+
471
+ impl < ' a , T , D > Drop for PyReadwriteArray < ' a , T , D > {
472
+ fn drop ( & mut self ) {
473
+ BORROW_FLAGS . release_mut ( self . 0 ) ;
419
474
}
420
475
}
421
476
0 commit comments