[Webkit-unassigned] [Bug 164922] [SOUP] Simplify custom protocols handler implementation

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Nov 22 23:26:13 PST 2016


https://bugs.webkit.org/show_bug.cgi?id=164922

--- Comment #21 from Carlos Garcia Campos <cgarcia at igalia.com> ---
(In reply to comment #20)
> (In reply to comment #18)
> > I learned it recently
> > the hard way in bug #164631. When using the sink paramater there's no move
> > constructor for the parameter so that when the value is moved the ownership
> > is transferred, but the moved value is not set to nullptr, you have to use
> > exchange or swap in that particular case if you need to ensure the value is
> > nullptr after the move.
> 
> I need to learn more about this. Could you show me a simple test program
> that demonstrates a moved value and a unique_ptr that is not set to nullptr
> after the value is moved out? I don’t think this exists, but a sample .cpp
> file could help me understand.

Sure, check this:

http://people.igalia.com/cgarcia/unique-sink.cpp

There are 3 cases:

 * Pass by value: a new unique_ptr is created and the move constructor is used. The new unique_ptr takes ownership and the other one is cleared.

 * Pass sink parameter: one of the advantages of move over the old PassRefPtr is that we don't need to adopt it to not leak it. So in this case the new owner doesn't call move again, it simply uses the value. In this case no other unique_ptr is created, as explained in the link you shared, and therefore the move constructor is not called, the received unique_ptr is exactly the same as the passed one, so it can't be cleared.

 * Pass sink parameter, but in this case the function moves again. In this case a new unique_ptr is created locally and the move constructor is called, clearing the passed unique_ptr.

Check the output of the program:

$ ./unique-sink 
value: u(0x7ffda4ba2410) p(0x55c06b529c20) v(25)
f1: u(0x7ffda4ba2400) p((nil)), v(0)
sink: u(0x7ffda4ba23f0) p(0x55c06b529c20) v(50)
f2: u(0x7ffda4ba23f0) p(0x55c06b529c20) v(50)
sinkAndMove: u(0x7ffda4ba23e0) p(0x55c06b52a050) v(150)
f3: u(0x7ffda4ba23e0) p((nil)) v(0)

u: unique_ptr
p: pointer
v: value

So, this is only a problem when we move a unique_ptr and the receiver doesn't move again to unique_ptr (but not to another unique_ptr&&, of course). In such cases if we want to ensure the unique_ptr is cleared we need to either use a local variable to move first and then transfer that, or use std::exchange, but in both cases the effect would be the same as passing by value, because a new unique_ptr will be created. The only way I can think of to avoid the creation of the second unique_ptr would be to explicitly set to nullptr after the function call:

sink (std::move(f1));
f1 = nullptr;

Instead of relying on move clearing the unique_ptr. If the function doesn't move again, the value is not useful after the function call, so we can clear it manually.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20161123/6d78e5d7/attachment-0001.html>


More information about the webkit-unassigned mailing list