Skip to content

Commit b646fbb

Browse files
committed
fix ref count for arrays used in indexing
The Array objects used by Indexer objects were not properly incrementing the reference count. This led to memory corruption and undefined behaviour which is fixed now.
1 parent de0278a commit b646fbb

File tree

2 files changed

+17
-27
lines changed

2 files changed

+17
-27
lines changed

src/index.rs

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,33 @@ use defines::AfError;
55
use error::HANDLE_ERROR;
66
use seq::Seq;
77
use self::libc::{c_double, c_int, c_uint};
8-
use util::{AfArray, DimT, IndexT, MutAfArray, MutAfIndex};
8+
use util::{AfArray, AfIndex, DimT, MutAfArray, MutAfIndex};
99

1010
#[allow(dead_code)]
1111
extern {
1212
fn af_create_indexers(indexers: MutAfIndex) -> c_int;
13-
fn af_set_array_indexer(indexer: MutAfIndex, idx: AfArray, dim: DimT) -> c_int;
14-
fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int;
15-
fn af_release_indexers(indexers: MutAfIndex) -> c_int;
13+
fn af_set_array_indexer(indexer: AfIndex, idx: AfArray, dim: DimT) -> c_int;
14+
fn af_set_seq_indexer(indexer: AfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int;
15+
fn af_release_indexers(indexers: AfIndex) -> c_int;
1616

1717
fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const SeqInternal) -> c_int;
1818
fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int;
1919
fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const SeqInternal, rhs: AfArray) -> c_int;
20-
fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: *const IndexT) -> c_int;
21-
fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: *const IndexT, rhs: AfArray) -> c_int;
20+
fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: AfIndex) -> c_int;
21+
fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: AfIndex, rhs: AfArray) -> c_int;
2222
}
2323

2424
/// Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct)
2525
pub struct Indexer {
2626
handle: i64,
27-
count: u32,
2827
}
2928

3029
// Trait that indicates that object can be used for indexing
3130
//
3231
// Any object to be able to be passed on to [./struct.Indexer.html#method.set_index] method
3332
// should implement this trait with appropriate implementation
3433
pub trait Indexable {
35-
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>);
34+
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>);
3635
}
3736

3837
/// Enables [Array](./struct.Array.html) to be used to index another Array
@@ -41,11 +40,10 @@ pub trait Indexable {
4140
/// [assign_gen](./fn.assign_gen.html)
4241
impl Indexable for Array {
4342
#[allow(unused_variables)]
44-
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) {
43+
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
4544
unsafe {
46-
let err_val = af_set_array_indexer(idxr.clone().get() as MutAfIndex,
47-
self.get() as AfArray,
48-
dim as DimT);
45+
let err_val = af_set_array_indexer(idxr.get() as AfIndex, self.clone().get() as AfArray,
46+
dim as DimT);
4947
HANDLE_ERROR(AfError::from(err_val));
5048
}
5149
}
@@ -56,9 +54,9 @@ impl Indexable for Array {
5654
/// This is used in functions [index_gen](./fn.index_gen.html) and
5755
/// [assign_gen](./fn.assign_gen.html)
5856
impl<T: Copy> Indexable for Seq<T> where c_double: From<T> {
59-
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) {
57+
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
6058
unsafe {
61-
let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex,
59+
let err_val = af_set_seq_indexer(idxr.get() as AfIndex,
6260
&SeqInternal::from_seq(self) as *const SeqInternal,
6361
dim as DimT, is_batch.unwrap() as c_int);
6462
HANDLE_ERROR(AfError::from(err_val));
@@ -74,33 +72,25 @@ impl Indexer {
7472
let mut temp: i64 = 0;
7573
let err_val = af_create_indexers(&mut temp as MutAfIndex);
7674
HANDLE_ERROR(AfError::from(err_val));
77-
Indexer{handle: temp, count: 0}
75+
Indexer{handle: temp}
7876
}
7977
}
8078

8179
/// Set either [Array](./struct.Array.html) or [Seq](./struct.Seq.html) to index an Array along `idx` dimension
8280
pub fn set_index<T: Indexable>(&mut self, idx: &T, dim: u32, is_batch: Option<bool>) {
83-
self.count = self.count + 1;
8481
idx.set(self, dim, is_batch)
8582
}
8683

8784
/// Get native(ArrayFire) resource handle
8885
pub fn get(&self) -> i64 {
8986
self.handle
9087
}
91-
92-
/// Get number of indexers
93-
///
94-
/// This can be a maximum of four since currently ArrayFire supports maximum of four dimensions
95-
pub fn len(&self) -> u32 {
96-
self.count
97-
}
9888
}
9989

10090
impl Drop for Indexer {
10191
fn drop(&mut self) {
10292
unsafe {
103-
let ret_val = af_release_indexers(self.handle as MutAfIndex);
93+
let ret_val = af_release_indexers(self.handle as AfIndex);
10494
match ret_val {
10595
0 => (),
10696
_ => panic!("Failed to release indexers resource: {}", ret_val),
@@ -338,7 +328,7 @@ pub fn index_gen(input: &Array, indices: Indexer) -> Array {
338328
unsafe{
339329
let mut temp: i64 = 0;
340330
let err_val = af_index_gen(&mut temp as MutAfArray, input.get() as AfArray,
341-
indices.len() as DimT, indices.get() as *const IndexT);
331+
4, indices.get() as AfIndex);
342332
HANDLE_ERROR(AfError::from(err_val));
343333
Array::from(temp)
344334
}
@@ -380,7 +370,7 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Array {
380370
unsafe{
381371
let mut temp: i64 = 0;
382372
let err_val = af_assign_gen(&mut temp as MutAfArray, lhs.get() as AfArray,
383-
indices.len() as DimT, indices.get() as *const IndexT,
373+
4, indices.get() as AfIndex,
384374
rhs.get() as AfArray);
385375
HANDLE_ERROR(AfError::from(err_val));
386376
Array::from(temp)

src/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ use self::num::Complex;
99
use self::libc::{uint8_t, c_int, size_t, c_void};
1010

1111
pub type AfArray = self::libc::c_longlong;
12+
pub type AfIndex = self::libc::c_longlong;
1213
pub type CellPtr = *const self::libc::c_void;
1314
pub type Complex32 = Complex<f32>;
1415
pub type Complex64 = Complex<f64>;
1516
pub type DimT = self::libc::c_longlong;
1617
pub type Feat = *const self::libc::c_void;
17-
pub type IndexT = self::libc::c_longlong;
1818
pub type Intl = self::libc::c_longlong;
1919
pub type MutAfArray = *mut self::libc::c_longlong;
2020
pub type MutAfIndex = *mut self::libc::c_longlong;

0 commit comments

Comments
 (0)