Bug 212379 - [WTF] Implement new BoxPtr alias
Summary: [WTF] Implement new BoxPtr alias
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Xabier Rodríguez Calvar
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-05-26 09:30 PDT by Xabier Rodríguez Calvar
Modified: 2020-07-09 09:29 PDT (History)
14 users (show)

See Also:


Attachments
Patch (20.47 KB, patch)
2020-05-26 09:32 PDT, Xabier Rodríguez Calvar
no flags Details | Formatted Diff | Diff
Patch (17.74 KB, patch)
2020-06-29 07:56 PDT, Xabier Rodríguez Calvar
no flags Details | Formatted Diff | Diff
Patch (17.64 KB, patch)
2020-07-07 10:04 PDT, Xabier Rodríguez Calvar
no flags Details | Formatted Diff | Diff
Patch (17.68 KB, patch)
2020-07-08 07:24 PDT, Xabier Rodríguez Calvar
darin: review+
Details | Formatted Diff | Diff
Patch (17.61 KB, patch)
2020-07-09 02:16 PDT, Xabier Rodríguez Calvar
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Xabier Rodríguez Calvar 2020-05-26 09:30:05 PDT
[WTF] Implement new BoxPtr class
Comment 1 Xabier Rodríguez Calvar 2020-05-26 09:32:54 PDT
Created attachment 400253 [details]
Patch
Comment 2 Xabier Rodríguez Calvar 2020-05-26 09:33:42 PDT
This class will be used in a further implementation of OpenCDM in the GStreamer based ports.
Comment 3 Sam Weinig 2020-05-26 10:04:09 PDT
Hey Xabier, how do you see this differing from std::unique_ptr?
Comment 4 Xabier Rodríguez Calvar 2020-05-26 21:57:25 PDT
(In reply to Sam Weinig from comment #3)
> Hey Xabier, how do you see this differing from std::unique_ptr?

This is shareable (it has copy constructor) and the pointer inside is deleted when when all refs are gone.
Comment 5 Michael Catanzaro 2020-05-27 08:16:36 PDT
Comment on attachment 400253 [details]
Patch

I understand the purpose of BoxPtr is to add refcounting to classes without an internal reference count. So... I think you have reinvented std::shared_ptr, yes? :)
Comment 6 Sam Weinig 2020-05-27 12:06:23 PDT
(In reply to Sam Weinig from comment #3)
> Hey Xabier, how do you see this differing from std::unique_ptr?

Oh, blergh, yeah. What I really should have asked is how this is different than WTF::Box<std::unique_ptr<T, Deleter>>?
Comment 7 Xabier Rodríguez Calvar 2020-05-29 07:34:50 PDT
I think Michael is right. For some reason I remember somebody telling me that shared_ptr was not a good idea inside WebKit and as in the code base I usually moved I had never seen it, I didn't even bother to check if it was used.

I just moved the OpenCDM code from BoxPtr to shared_ptr and everything works as expected so I'll close this.
Comment 8 Michael Catanzaro 2020-05-29 08:25:59 PDT
(In reply to Xabier Rodríguez Calvar from comment #7)
> I think Michael is right. For some reason I remember somebody telling me
> that shared_ptr was not a good idea inside WebKit and as in the code base I
> usually moved I had never seen it, I didn't even bother to check if it was
> used.

Well... shared_ptr is *usually* not a good idea, because we use RefPtr instead, for RefCounted classes. But when you have an external class provided by an external library that doesn't have an internal refcount, then RefPtr is not an option, and std::shared_ptr is a good solution. Currently I see one use in JSC and three in WTF, which is not much precedent for using shared_ptr in WebKit, but that's OK since it's the right tool for what you need to do.

It's a shame you wrote all those tests that will not be committed. :(
Comment 9 Sam Weinig 2020-05-29 09:12:24 PDT
There is also the existing WTF::Box class, which should support this use case in many places.
Comment 10 Xabier Rodríguez Calvar 2020-05-29 10:14:23 PDT
(In reply to Sam Weinig from comment #9)
> There is also the existing WTF::Box class, which should support this use
> case in many places.

Yes, but not in this one because Box is thought for objects that can be built in place and in this case the you get a "C object" created with a function and returned as a struct. I had actually named BoxPtr because it was a very similar use case but not needing to have the object in place.

Could I use Box<std::unique_ptr<OpenCDMSession>>? Probably yes, but IMHO it's quite a convolution if shared_ptr does the job.
Comment 11 Konstantin Tokarev 2020-05-29 10:18:02 PDT
(In reply to Xabier Rodríguez Calvar from comment #10)
> Could I use Box<std::unique_ptr<OpenCDMSession>>? Probably yes, but IMHO
> it's quite a convolution if shared_ptr does the job.

FWIW, Box uses FastMalloc while shared_ptr doesn't, and we could add an alias for Box<std::unique_ptr<T>>
Comment 12 Xabier Rodríguez Calvar 2020-06-29 07:55:42 PDT
(In reply to Konstantin Tokarev from comment #11)
> FWIW, Box uses FastMalloc while shared_ptr doesn't, and we could add an
> alias for Box<std::unique_ptr<T>>

Let's try this then.
Comment 13 Xabier Rodríguez Calvar 2020-06-29 07:56:10 PDT
Created attachment 403057 [details]
Patch
Comment 14 Konstantin Tokarev 2020-06-30 08:02:12 PDT
Comment on attachment 403057 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403057&action=review

> Source/WTF/wtf/BoxPtr.h:54
> +    return Box<std::unique_ptr<T, BoxPtrDeleter<T>>>::create(ptr);

This can be shortened to BoxPtr<T>::create(ptr)
Comment 15 Darin Adler 2020-06-30 10:51:09 PDT
I, for one, would prefer that we use std::shared_ptr rather than making our own. But maybe we can’t figure out how to make shared_ptr use FastMalloc by default?
Comment 16 Michael Catanzaro 2020-06-30 11:09:48 PDT
(In reply to Darin Adler from comment #15)
> I, for one, would prefer that we use std::shared_ptr rather than making our
> own. But maybe we can’t figure out how to make shared_ptr use FastMalloc by
> default?

We could create a ::create static factory function as usual that would call std::allocate_shared with an appropriate allocator. We would have to think about using FastMalloc when writing the ::create function, but not in all the dozens of places we might want to create new objects.

I don't think something like WTF_MAKE_FAST_ALLOCATED would be possible, though.
Comment 17 Xabier Rodríguez Calvar 2020-07-03 03:11:54 PDT
Well, I'm going to go ahead with the patch that I had depending on this with std::shared_ptr. If we agree on somthing eventually, I'll change it later.
Comment 18 Darin Adler 2020-07-04 07:40:13 PDT
Comment on attachment 403057 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403057&action=review

> Source/WTF/wtf/BoxPtr.h:36
> +    void operator()(T*) const { ASSERT_NOT_REACHED(); }

I think if we define this without a function body, we get something even better. A link time error rather than a runtime assertion. Maybe even a compile time error.

> Source/WTF/wtf/BoxPtr.h:39
> +#define WTF_DEFINE_BOXPTR_DELETER(typeName, deleterFunc)        \

In WebKit we don’t use abbreviations like “func“. Please call this function not func.

> Source/WTF/wtf/BoxPtr.h:58
> +bool operator==(const BoxPtr<T>& lhs, const BoxPtr<T>& rhs)

This is quite risky. Doing this for == and not !=, and also the effect this could have a generic code that really does need to do a pointer equality. I understand this is the heart of what you mean by using a pointer to box something, but I am quite concerned that this technique may not work well.

> Tools/TestWebKitAPI/Tests/WTF/BoxPtr.cpp:163
> +#if COMPILER(CLANG)

Compiler.h has macros for this kind of thing, and we should use those.
Comment 19 Konstantin Tokarev 2020-07-04 17:43:49 PDT
Comment on attachment 403057 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403057&action=review

>> Source/WTF/wtf/BoxPtr.h:36
>> +    void operator()(T*) const { ASSERT_NOT_REACHED(); }
> 
> I think if we define this without a function body, we get something even better. A link time error rather than a runtime assertion. Maybe even a compile time error.

"void operator()(T*) const = delete" would make it compile error
Comment 20 Xabier Rodríguez Calvar 2020-07-07 10:04:53 PDT
Created attachment 403705 [details]
Patch

Addressed all comments.

(In reply to Darin Adler from comment #18)
> > Source/WTF/wtf/BoxPtr.h:58
> > +bool operator==(const BoxPtr<T>& lhs, const BoxPtr<T>& rhs)
> 
> This is quite risky. Doing this for == and not !=, and also the effect this
> could have a generic code that really does need to do a pointer equality. I
> understand this is the heart of what you mean by using a pointer to box
> something, but I am quite concerned that this technique may not work well.

In my use case it helps, otherwise I would have to do the comparison by myself.
Comment 21 Darin Adler 2020-07-07 10:07:50 PDT
(In reply to Xabier Rodríguez Calvar from comment #20)
> In my use case it helps, otherwise I would have to do the comparison by
> myself.

Obviously. My comment was about all the other repercussions. Leaving out != seems especially capricious.
Comment 22 Konstantin Tokarev 2020-07-08 02:32:07 PDT
Comment on attachment 403705 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403705&action=review

> Source/WTF/wtf/BoxPtr.h:78
> +    return !(*lhs == *rhs);

I think it was meant to be implemented via operator== defined above, i.e.

    return !(lhs == rhs);
Comment 23 Xabier Rodríguez Calvar 2020-07-08 06:57:39 PDT
(In reply to Konstantin Tokarev from comment #22)
> Comment on attachment 403705 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=403705&action=review
> 
> > Source/WTF/wtf/BoxPtr.h:78
> > +    return !(*lhs == *rhs);
> 
> I think it was meant to be implemented via operator== defined above, i.e.
> 
>     return !(lhs == rhs);

Definitely. I guess I should have written tests for that as well and then I would realized...
Comment 24 Xabier Rodríguez Calvar 2020-07-08 07:24:10 PDT
Created attachment 403778 [details]
Patch

(In reply to Xabier Rodríguez Calvar from comment #23)
> (In reply to Konstantin Tokarev from comment #22)
> > Comment on attachment 403705 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=403705&action=review
> > 
> > > Source/WTF/wtf/BoxPtr.h:78
> > > +    return !(*lhs == *rhs);
> > 
> > I think it was meant to be implemented via operator== defined above, i.e.
> > 
> >     return !(lhs == rhs);
> 
> Definitely. I guess I should have written tests for that as well and then I
> would realized...

And no, the test intent was there but the test was wrong so it was still passing. I added another test to test against empty BoxPtrs that was making former code crash. This works.
Comment 25 Darin Adler 2020-07-08 11:12:37 PDT
Comment on attachment 403778 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403778&action=review

> Source/WTF/wtf/BoxPtr.h:35
> +template<typename T>
> +struct BoxPtrDeleter {

I personally like the style where template is on the same line. Applies to all the lines in this file.

> Source/WTF/wtf/BoxPtr.h:39
> +#define WTF_DEFINE_BOXPTR_DELETER(typeName, deleterFunction)        \

Seems like this is a little bit hard to use correctly, but let's try this for now. Also, I suggest just one space before the \ rather than different amounts on each line.
Comment 26 Xabier Rodríguez Calvar 2020-07-09 02:16:01 PDT
Created attachment 403853 [details]
Patch

(In reply to Darin Adler from comment #25)
> Comment on attachment 403778 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=403778&action=review
> 
> > Source/WTF/wtf/BoxPtr.h:35
> > +template<typename T>
> > +struct BoxPtrDeleter {
> 
> I personally like the style where template is on the same line. Applies to
> all the lines in this file.

Done.

> > Source/WTF/wtf/BoxPtr.h:39
> > +#define WTF_DEFINE_BOXPTR_DELETER(typeName, deleterFunction)        \
> 
> Seems like this is a little bit hard to use correctly, but let's try this
> for now. Also, I suggest just one space before the \ rather than different
> amounts on each line.

Done.

I also indented the compiler checks and removed some of the checks I was doing because they were redundant (as the macros already check if the warning is available or not) and because piling up BEGINs like that was creating compiler diagnostic contexts I was not removing.
Comment 27 EWS 2020-07-09 02:36:57 PDT
Committed r264163: <https://trac.webkit.org/changeset/264163>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 403853 [details].
Comment 28 Radar WebKit Bug Importer 2020-07-09 02:37:15 PDT
<rdar://problem/65263992>
Comment 29 Darin Adler 2020-07-09 08:50:59 PDT
Comment on attachment 403853 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=403853&action=review

> Source/WTF/wtf/BoxPtr.h:51
> +    return Box<std::unique_ptr<T, BoxPtrDeleter<T>>>::create(ptr);

I don’t understand why we didn’t write this instead:

    return BoxPtr<T>::create(ptr);
Comment 30 Xabier Rodríguez Calvar 2020-07-09 09:29:17 PDT
(In reply to Darin Adler from comment #29)
> Comment on attachment 403853 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=403853&action=review
> 
> > Source/WTF/wtf/BoxPtr.h:51
> > +    return Box<std::unique_ptr<T, BoxPtrDeleter<T>>>::create(ptr);
> 
> I don’t understand why we didn’t write this instead:
> 
>     return BoxPtr<T>::create(ptr);

To be fixed in bug 214144.