Bug 14225 - Make it possible to define platform-specific ResourceRequest without #ifdefs
Summary: Make it possible to define platform-specific ResourceRequest without #ifdefs
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: 523.x (Safari 3)
Hardware: All All
: P3 Minor
Assignee: Darin Fisher (:fishd, Google)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-18 19:35 PDT by Darin Fisher (:fishd, Google)
Modified: 2010-10-05 15:47 PDT (History)
2 users (show)

See Also:


Attachments
partial patch (mac only) (45.52 KB, patch)
2007-06-18 19:38 PDT, Darin Fisher (:fishd, Google)
no flags Details | Formatted Diff | Diff
partial patch v2 (mac only) (45.58 KB, patch)
2007-06-19 20:39 PDT, Darin Fisher (:fishd, Google)
darin: review-
Details | Formatted Diff | Diff
partial patch v2.1 (mac only) (45.60 KB, patch)
2007-06-22 12:56 PDT, Darin Fisher (:fishd, Google)
mjs: review-
Details | Formatted Diff | Diff
complete patch (56.37 KB, patch)
2007-06-26 01:31 PDT, Darin Fisher (:fishd, Google)
no flags Details | Formatted Diff | Diff
complete patch (that actually works!) (56.69 KB, patch)
2007-06-26 01:50 PDT, Darin Fisher (:fishd, Google)
mjs: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Fisher (:fishd, Google) 2007-06-18 19:35:43 PDT
Make it possible to define platform-specific ResourceRequest without #ifdefs

Move ResourceRequest into a platform-specific directory, and have it extend from a BaseResourceRequest that carries the bulk of the code for the ResourceRequest.

See patch.
Comment 1 Darin Fisher (:fishd, Google) 2007-06-18 19:38:16 PDT
Created attachment 15112 [details]
partial patch (mac only)

OK, this patch does the trick for PLATFORM(MAC).  If this approach is acceptable, then I will do the same for the USE(CFNETWORK).
Comment 2 Darin Fisher (:fishd, Google) 2007-06-19 09:01:31 PDT
I thought about this patch some more, and perhaps it would be better to declare doUpdate* methods as virtual on the base class.  (This is somewhat of a textbook example of when you should use virtual functions.)  The cost of doing so would not be measurable in the product since we rarely call those methods, and moreover the work they do far outweighs the cost of the virtual functions.  If desired, I will make that modification.

Maciej asked in #webkit about finding a good pattern to apply universally to classes in the porting layer.  The two choices being virtual functions or downcasting.  I think that we'll have a better idea once more classes are converted.  In many cases, virtual functions would be more than appropriate, but we'll have to see.
Comment 3 Darin Fisher (:fishd, Google) 2007-06-19 19:43:11 PDT
OK, I discussed this more with Maciej in #webkit, and we agreed on the following:

1. Name things FooBase instead of BaseFoo.  Hyatt was also happier with this.

2. Go with the downcasting approach, but invent a method for the downcast operation.  In this case, it would be something like this:

  class ResourceRequestBase
  {
      ...
  private:
      ResourceRequest& asResourceRequest() {
          return *static_cast<ResourceRequest*>(this);
      }
      const ResourceRequest& asResourceRequest() const {
          return *static_cast<const ResourceRequest*>(this);       
      }
  };

This naming convention is nice because it addresses situations where we have multiple FooBase classes in a heirarchy.
Comment 4 Darin Fisher (:fishd, Google) 2007-06-19 20:39:26 PDT
Created attachment 15133 [details]
partial patch v2 (mac only)

OK, this implements the revised approach:
asResourceRequest() + ResourceRequestBase
Comment 5 Darin Adler 2007-06-20 10:11:41 PDT
Comment on attachment 15133 [details]
partial patch v2 (mac only)

I'm a little concerned about having files with identical names but different contents in the various platform-specific subdirectories. Up until this point we've mostly avoided this, and it helps with build systems that have trouble understanding identically named source files. But I don't see an elegant alternative, so I guess we should go with it.

+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSURLRequest;
+#else
+class NSURLRequest;
+#endif
+#endif

I don't think that ResourceRequest.h in the mac subdirectory needs an #if PLATFORM(MAC). So you can just remove the ifdef.

+#include "config.h"
+#include "ResourceRequest.h"

I think it would be slightly better to explicitly include first "ResourceRequestBase.h" and then "ResourceRequest.h", even though that amounts to the same thing as just including "ResourceRequest.h". I want to take our "always includes your own header first" rule literally in cases like this.

+    const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();

I believe this won't compile. It's not just a  const_cast, it's also a downcast, so it needs to be a combination of const_cast and static_cast or a C-style cast. Did you try compiling this?

I'd slightly prefer it if we could come up with a way to do the downcast to ResourceRequest without a static_cast at each call site. Maybe an inline helper function would make the syntax a little sweeter?
Comment 6 Darin Adler 2007-06-20 10:11:41 PDT
Comment on attachment 15133 [details]
partial patch v2 (mac only)

I'm a little concerned about having files with identical names but different contents in the various platform-specific subdirectories. Up until this point we've mostly avoided this, and it helps with build systems that have trouble understanding identically named source files. But I don't see an elegant alternative, so I guess we should go with it.

+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSURLRequest;
+#else
+class NSURLRequest;
+#endif
+#endif

I don't think that ResourceRequest.h in the mac subdirectory needs an #if PLATFORM(MAC). So you can just remove the ifdef.

+#include "config.h"
+#include "ResourceRequest.h"

I think it would be slightly better to explicitly include first "ResourceRequestBase.h" and then "ResourceRequest.h", even though that amounts to the same thing as just including "ResourceRequest.h". I want to take our "always includes your own header first" rule literally in cases like this.

+    const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();

I believe this won't compile. It's not just a  const_cast, it's also a downcast, so it needs to be a combination of const_cast and static_cast or a C-style cast. Did you try compiling this?

I'd slightly prefer it if we could come up with a way to do the downcast to ResourceRequest without a static_cast at each call site. Maybe an inline helper function would make the syntax a little sweeter?
Comment 7 Darin Fisher (:fishd, Google) 2007-06-20 18:03:30 PDT
> +#if PLATFORM(MAC)
> +#include <wtf/RetainPtr.h>
> +#ifdef __OBJC__
> +@class NSURLRequest;
> +#else
> +class NSURLRequest;
> +#endif
> +#endif
> 
> I don't think that ResourceRequest.h in the mac subdirectory needs an #if
> PLATFORM(MAC). So you can just remove the ifdef.

Oops, yes.  That is spurious.  I will remove it.


> +#include "config.h"
> +#include "ResourceRequest.h"
> 
> I think it would be slightly better to explicitly include first
> "ResourceRequestBase.h" and then "ResourceRequest.h", even though that amounts
> to the same thing as just including "ResourceRequest.h". I want to take our
> "always includes your own header first" rule literally in cases like this.

OK, sure thing.


> +   
> const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
> 
> I believe this won't compile. It's not just a  const_cast, it's also a
> downcast, so it needs to be a combination of const_cast and static_cast or a
> C-style cast. Did you try compiling this?

Yes, I compiled and Safari runs fine with this code.  I think you should look at the implementation of asResourceRequest(), which performs the downcast operation.  The const_cast is needed to call a non-const method on the ResourceRequest.


> I'd slightly prefer it if we could come up with a way to do the downcast to
> ResourceRequest without a static_cast at each call site. Maybe an inline helper
> function would make the syntax a little sweeter?

That would be asResourceRequest :-)  It is not inline however because I would have to define it after the #include of ResourceRequest.h, which would be messy.  I believe that any good compiler/linker will optimize away the function.
Comment 8 Darin Fisher (:fishd, Google) 2007-06-22 12:56:08 PDT
Created attachment 15187 [details]
partial patch v2.1 (mac only)

OK, revised according to review feedback.  Please let me know if this is an OK approach, and then I will contribute a CFNet version as well.  Thanks!
Comment 9 Maciej Stachowiak 2007-06-25 22:42:26 PDT
Comment on attachment 15187 [details]
partial patch v2.1 (mac only)

Looks good to me. We need at least a CFNetwork version as well to land this (assuming it breaks the ResourceRequest build for other platforms). And I think it would be good to convert the Qt and curl versions as well, to avoid breaking the build for the Qt and Gtk ports. Otherwise looks great. Please submit a new version that covers other platforms.
Comment 10 Darin Fisher (:fishd, Google) 2007-06-26 01:31:41 PDT
Created attachment 15240 [details]
complete patch

OK, this covers all of the major network platforms: mac, cf, qt, and curl.
Comment 11 Darin Fisher (:fishd, Google) 2007-06-26 01:50:04 PDT
Created attachment 15241 [details]
complete patch (that actually works!)

was a link error in the previous patch.  use this one instead.
Comment 12 Maciej Stachowiak 2007-06-26 19:33:44 PDT
Comment on attachment 15241 [details]
complete patch (that actually works!)

Looks ok, please try to get someone to land this at a time when it is easy to follow the build bots and land appropriate follow-up fixes.

r=me
Comment 13 Mark Rowe (bdash) 2007-06-26 20:17:21 PDT
Landed in r23806.
Comment 14 Simon Fraser (smfr) 2010-10-05 11:58:44 PDT
> (In reply to comment #5)
> (From update of attachment 15133 [details])
> I'm a little concerned about having files with identical names but different contents in the various platform-specific subdirectories.

This exact issue was the cause of the recent WebSocket memory smasher (Mac Xcode project picked up the qt header).
Comment 15 Darin Fisher (:fishd, Google) 2010-10-05 15:47:36 PDT
(In reply to comment #14)
> > (In reply to comment #5)
> > (From update of attachment 15133 [details] [details])
> > I'm a little concerned about having files with identical names but different contents in the various platform-specific subdirectories.
> 
> This exact issue was the cause of the recent WebSocket memory smasher (Mac Xcode project picked up the qt header).

How was it that the Xcode build was including headers from a different port?  How likely is that problem to repeat?

Perhaps the ResourceRequest.h headers should all have PLATFORM-specific guards so that if PLATFORM(QT) is not defined then ResourceRequest would also not be defined.  That would turn this kind of mistake into a compile time error.