Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd the ability to borrow values from the array. #147
Conversation
|
I like this approach. It doesn't appear to have any downsides that I can see. |
| TCFType::wrap_under_get_rule(mem::transmute(x)) | ||
| unsafe impl<T: TCFType> FromVoid for T where T::Ref: FromVoid { | ||
| unsafe fn from_void(x: *const c_void) -> Self { | ||
| TCFType::wrap_under_get_rule(T::Ref::from_void(x)) |
This comment has been minimized.
This comment has been minimized.
faern
Jan 23, 2018
Contributor
TCFType::Ref is already forced to implement TCFTypeRef, which has a from_void_ptr method. So you could remove where T::Ref: FromVoid and use T::Ref::from_void_ptr(x) instead. Would work the same, but would be slightly simpler/more minimal maybe?
This comment has been minimized.
This comment has been minimized.
|
|
||
| unsafe impl FromVoidBorrow for u32 { | ||
| unsafe fn from_void_borrow<'a>(x: *const c_void) -> TCFTypeBorrow<'a, Self> { | ||
| TCFTypeBorrow(x as usize as u32, PhantomData) |
This comment has been minimized.
This comment has been minimized.
faern
Jan 23, 2018
Contributor
I do not understand this casting. Maybe I'm just too tired. There is no dereferencing of the pointer, so would the resulting u32 not contain the pointer address? Quite likely a truncated version of it as well.
This comment has been minimized.
This comment has been minimized.
jrmuizel
Jan 24, 2018
Author
Collaborator
Yes, it's intentionally not dereferencing it. I've added a comment to explain it more and dropped the 'as usize' as it doesn't seem to be necessary.
|
I've cleaned this up by renaming TCFTypeBorrow to ItemRef, replacing FromVoid with FromVoidBorrow and making get() return an ItemRef instead of having a separate get_borrow() |
| TCFType::wrap_under_get_rule(mem::transmute(x)) | ||
| unsafe impl<T: TCFType> FromVoid for T { | ||
| unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> { | ||
| ItemRef(TCFType::wrap_under_create_rule(T::Ref::from_void_ptr(x)), PhantomData) |
This comment has been minimized.
This comment has been minimized.
faern
Jan 24, 2018
Contributor
Won't the drop of the constructed T do a CFRelease and make the retain count wrong? If you construct a new T from a void pointer, should you not do it under the get rule?
Could you add a test that checks retain counts are correct before and after borrowing values from the array?
Also, nitpicking: T::wrap_under_... should work as well? Making it a bit more clear which type we create here.
This comment has been minimized.
This comment has been minimized.
jrmuizel
Jan 24, 2018
Author
Collaborator
Yep. I've messed up the reference counts here. I need to think about how to fix it. wraping with the get rule will increase the retain count which defeats the point of this patch.
This comment has been minimized.
This comment has been minimized.
faern
Jan 24, 2018
Contributor
The underlying ffi function, CFArrayGetValueAtIndex specifies that values returned should follow the get rule. So if you would use CFArray directly in Objective-C you would likely bump the retain count? So is there any reason we should be allowed not to? If we convert the value into a CF object and hold a reference to that then should the retain count not reflect how many handles there are to that object?
This comment has been minimized.
This comment has been minimized.
jrmuizel
Jan 24, 2018
Author
Collaborator
Rust, in theory, should let us use the existing reference in the array safely. Since its lifetime will be tied to the array we should be able to interact with those objects without needing to bump the retain count.
i.e. imagine if you have Vec<Rc>. You can iterate over them without having to bump the reference counts on all of the objects.
This comment has been minimized.
This comment has been minimized.
faern
Jan 24, 2018
Contributor
Yes true. As long as the borrow can't outlive the array yes indeed!
How about you just mem::forget the T value in the Drop impl for ItemRef?
This comment has been minimized.
This comment has been minimized.
jrmuizel
Jan 24, 2018
Author
Collaborator
fn drop takes &mut self so it won't let me just mem::forget() the T value
This comment has been minimized.
This comment has been minimized.
|
@jrmuizel Would it not be nice to get rid of the possible panic in If we talk about performance, the current Is the array not guaranteed to be immutable? If so, the length of the array can be queried once and stored in the iterator for comparison without doing the ffi call to |
7d34492
to
be0bdd5
|
I implemented the bounds checking in #148 |
This uses borrowed values from the array to avoid having to Retain/Release during iteration. It also implements borrowing for all TCFType.
|
This is ready for review. It would be good to get this into the 0.5 release so we avoid breaking compat twice. |
|
@bors-servo: r+ |
|
|
Add the ability to borrow values from the array. This is a replacement for #143. It allows iteration while avoiding the reference count churn of the previous approach. It uses a TCFTypeBorrow (could probably use a better name) to hold a sort of reference to the array data. I'm interested in people's thoughts and opinions on this approach. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/core-foundation-rs/147) <!-- Reviewable:end -->
|
|
jrmuizel commentedJan 23, 2018
•
edited by larsbergstrom
This is a replacement for #143. It allows iteration while avoiding the reference count churn of the previous approach. It uses a TCFTypeBorrow (could probably use a better name) to hold a sort of reference to the array data. I'm interested in people's thoughts and opinions on this approach.
This change is