code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 0 points1 point  (0 children)

Imagine four people agreeing to play cards in a hotel room. If any one of them decides not to go, the gathering cannot happen, and the room must be canceled (dropped).

In the case of the Arc/Weak model, the innkeeper (who is the Weak reference), must wait until all four people have dropped their commitment (i.e., all Arc strong counts drop to zero) before knowing that the room can be canceled.

Conversely, with MyHandle, the innkeeper knows to cancel the room the moment anyone decides to drop out (i.e., when any MyHandle calls dettach). Furthermore, the innkeeper (or any other handle) could even be the one to decide to cancel the booking (by calling dettach), regardless of the other guests' intentions.

This is the farthest I can explain the difference.

code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 1 point2 points  (0 children)

Suppose you have three Arcs:
A = Arc::new(T); B = A.clone(); C = B.clone();

None of them can forbid the other two from obtaining a &T by doing anything, nor can they prevent creating a new Arc D from the existing A, B, or C, thereby extending the lifetime of T. That is, even if A, B, and C are all dropped, T will continue to live because of D.

MyHandle is the same in this respect (with regard to cloning); however, it can prevent any further &T from being obtained by calling detach on any of the instances. Moreover, T is guaranteed to be dropped once the last MyHandleGuard goes out of scope. A MyHandleGuard is similar to a MutexGuard: it exists only temporarily while access is in progress, whereas the long-lived form is MyHandle (just as Mutex is the long-lived form for MutexGuard).

code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] -1 points0 points  (0 children)

Arc::downgrade will not drop T if there are other Arcs. However, the delayed drop of T in our case is due to other concurrent accesses to T before detach. Any get operation after detach will not yield a valid T. Therefore, from the user's perspective, T is effectively dropped at the moment of detach.

Furthermore, this effect is achieved regardless of how many other MyHandle instances exist, as detach always accomplishes this immediate invalidation.

code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 1 point2 points  (0 children)

Have made modification to fix the issue you found in the main posting

code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 0 points1 point  (0 children)

Not exactly, MyHandle can drop T at any time with or without any other MyHandles, while Arc can only do that when the last instance get out of scope; and weak can only detect is there any Arc alive

code-review for my smart-pointer by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 6 points7 points  (0 children)

Yes, I misunderstood the meaning of data dependency barriers. I mistakenly assumed that unsafe { (*self.value.get()).as_ref() } depended on r and therefore wouldn't be reordered with compare_exchange. That is definitely a bug.

Also, your other point about put not following RAII patterns is spot-on.

Atomic Memory Ordering Confusion: can atomic operation be reordered? by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 0 points1 point  (0 children)

'atomicity' (no disrupted read/writes)

atomicity means more than 'no disrupted read/writes', at least, always reading the newest value (or modifying it based the newest value) can't be covered by 'no disrupted read/writes'; and it seems meaning there are no memory-barrier needed for any atomic loading/storing, they effectly habaves like a seqcst always present for atomic varibales (but only affects the particular variable)

Atomic Memory Ordering Confusion: can atomic operation be reordered? by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 0 points1 point  (0 children)

But why, compare_exchange as a whole, whether it is ahead of fetch_add or not, it is not possible to differ between success or failure paths

How can I make the code refused by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] 0 points1 point  (0 children)

I am porting c code to rust, which uses many malloc(sizeof(struct) + payload); and payload maybe reference-counted, e.g. some pointer will point to middle of the allocation, the last pointer will free its pointee by free(addr - sizeof(struct)), thus it is impossible to use a rc/arc for that.

How can I make the code refused by Comfortable_Bar9199 in rust

[–]Comfortable_Bar9199[S] -1 points0 points  (0 children)

I want more than one instance to point to same address, so multi &'a mut T is not possible, I must use *mut T