Changeset 230529 in webkit
- Timestamp:
- Apr 11, 2018 9:58:23 AM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r230524 r230529 1 2018-04-11 Michael Catanzaro <mcatanzaro@igalia.com> 2 3 [GTK] WaylandCompositorDisplay leaks its wl_display 4 https://bugs.webkit.org/show_bug.cgi?id=184406 5 6 Reviewed by Carlos Garcia Campos. 7 8 Well, this was harder than expected. We really just want to fix a small leak in the WebKit 9 layer, but that requires a change in how WaylandCompositorDisplay calls the 10 PlatformDisplayWayland constructor, to pass NativeDisplayOwned::Yes. That means 11 WaylandCompositorDisplay can no longer use PlatformDisplayWayland's protected default 12 constructor. Problem is that the normal PlatformDisplayWayland constructor calls 13 PlatformDisplayWayland::initialize, which calls PlatformDisplayWayland::registryGlobal, 14 which is a virtual function. The WaylandCompositorDisplay portion of the object is not 15 constructed yet at this point, so WaylandCompositorDisplay::registryGlobal will never be 16 called if we do that. I had to revert the previous version of this fix due to this problem. 17 It had broken accelerated compositing. 18 19 I'm reminded of Effective C++ item #9: Never call virtual functions during construction or 20 destruction ("because such calls will never go to a more derived class than that of the 21 currently executing constructor or destructor"). This code is fragile and likely to break 22 again in the future, so let's refactor it a bit. Instead of calling initialize in the 23 constructor, we'll call it from create functions. We'll have to add a couple create 24 functions, and make the constructor protected to ensure it's not possible to create a 25 PlatformDisplayWayland without initializing it. For good parallelism, do the same for the 26 other PlatformDisplay classes. 27 28 This commit additionally removes PlatformDisplayWayland's protected default constructor, 29 since it's not needed anymore. 30 31 The NativeDisplayOwned arguments to the PlatformDisplay constructors are now mandatory, 32 instead of using NativeDisplayOwned::No as the default value, since that was dangerously 33 close to being the cause of this leak, and the constructors are now accessed from private 34 create functions anyway. Some more caution when using default parameter values is warranted 35 in the future. 36 37 Lastly, since we have to change PlatformDisplay::createPlatformDisplay to use the new create 38 functions, take the opportunity to move things around a bit for clarity. There should be no 39 change in behavior. I was just disappointed that the PlatformDisplayWPE creation was at the 40 bottom of the function, after a comment indicating that normal display creation has failed, 41 which is not the case for WPE. 42 43 This all might have been a bit overkill, since the leak could probably have been fixed by 44 passing nullptr to the PlatformDisplayWayland constructor for the wl_display and not 45 removing WaylandCompositorDisplay's call to PlatformDisplayWayland::initialize. But the 46 correctness of that code would then rely on implementation details of initialize, so this 47 refactor seems better. 48 49 No new tests since there *should* be no behavior change. Then again, I'm touching 50 PlatformDisplay, and history shows we don't have the greatest track record of touching this 51 code without introducing problems. 52 53 * platform/graphics/PlatformDisplay.cpp: 54 (WebCore::PlatformDisplay::createPlatformDisplay): 55 * platform/graphics/PlatformDisplay.h: 56 * platform/graphics/wayland/PlatformDisplayWayland.cpp: 57 (WebCore::PlatformDisplayWayland::create): 58 (WebCore::PlatformDisplayWayland::create): 59 (WebCore::PlatformDisplayWayland::createHeadless): 60 (WebCore::PlatformDisplayWayland::PlatformDisplayWayland): 61 (WebCore::PlatformDisplayWayland::initialize): 62 * platform/graphics/wayland/PlatformDisplayWayland.h: 63 * platform/graphics/win/PlatformDisplayWin.h: 64 * platform/graphics/wpe/PlatformDisplayWPE.cpp: 65 (WebCore::create): 66 * platform/graphics/wpe/PlatformDisplayWPE.h: 67 * platform/graphics/x11/PlatformDisplayX11.cpp: 68 (WebCore::PlatformDisplayX11::create): 69 (WebCore::PlatformDisplayX11::create): 70 (WebCore::PlatformDisplayX11::createHeadless): 71 * platform/graphics/x11/PlatformDisplayX11.h: 72 1 73 2018-04-11 Jianjun Zhu <jianjun.zhu@intel.com> 2 74 -
trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp
r224347 r230529 76 76 #if PLATFORM(GTK) 77 77 #if defined(GTK_API_VERSION_2) 78 return std::make_unique<PlatformDisplayX11>(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()));78 return PlatformDisplayX11::create(GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); 79 79 #else 80 80 GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get()); 81 81 #if PLATFORM(X11) 82 82 if (GDK_IS_X11_DISPLAY(display)) 83 return std::make_unique<PlatformDisplayX11>(GDK_DISPLAY_XDISPLAY(display));83 return PlatformDisplayX11::create(GDK_DISPLAY_XDISPLAY(display)); 84 84 #endif 85 85 #if PLATFORM(WAYLAND) 86 86 if (GDK_IS_WAYLAND_DISPLAY(display)) 87 return std::make_unique<PlatformDisplayWayland>(gdk_wayland_display_get_wl_display(display)); 88 #endif 89 #endif 87 return PlatformDisplayWayland::create(gdk_wayland_display_get_wl_display(display)); 88 #endif 89 #endif 90 #endif // PLATFORM(GTK) 91 92 #if PLATFORM(WPE) 93 return PlatformDisplayWPE::create(); 90 94 #elif PLATFORM(WIN) 91 return std::make_unique<PlatformDisplayWin>();95 return PlatformDisplayWin::create(); 92 96 #endif 93 97 … … 104 108 // If at this point we still don't have a display, just create a fake display with no native. 105 109 #if PLATFORM(WAYLAND) 106 return std::make_unique<PlatformDisplayWayland>(nullptr); 107 #endif 108 #if PLATFORM(X11) 109 return std::make_unique<PlatformDisplayX11>(nullptr); 110 #endif 111 112 #if PLATFORM(WPE) 113 return std::make_unique<PlatformDisplayWPE>(); 114 #endif 115 116 ASSERT_NOT_REACHED(); 117 return nullptr; 110 return PlatformDisplayWayland::create(nullptr); 111 #elif PLATFORM(X11) 112 return PlatformDisplayX11::create(nullptr); 113 #endif 114 115 RELEASE_ASSERT_NOT_REACHED(); 118 116 } 119 117 -
trunk/Source/WebCore/platform/graphics/PlatformDisplay.h
r230229 r230529 74 74 protected: 75 75 enum class NativeDisplayOwned { No, Yes }; 76 explicit PlatformDisplay(NativeDisplayOwned = NativeDisplayOwned::No);76 explicit PlatformDisplay(NativeDisplayOwned); 77 77 78 78 static void setSharedDisplayForCompositing(PlatformDisplay&); -
trunk/Source/WebCore/platform/graphics/wayland/PlatformDisplayWayland.cpp
r229525 r230529 57 57 return nullptr; 58 58 59 return std::make_unique<PlatformDisplayWayland>(display, NativeDisplayOwned::Yes); 59 auto platformDisplay = std::unique_ptr<PlatformDisplayWayland>(new PlatformDisplayWayland(display, NativeDisplayOwned::Yes)); 60 platformDisplay->initialize(); 61 return platformDisplay; 62 } 63 64 std::unique_ptr<PlatformDisplay> PlatformDisplayWayland::create(struct wl_display* display) 65 { 66 auto platformDisplay = std::unique_ptr<PlatformDisplayWayland>(new PlatformDisplayWayland(display, NativeDisplayOwned::No)); 67 platformDisplay->initialize(); 68 return platformDisplay; 60 69 } 61 70 62 71 PlatformDisplayWayland::PlatformDisplayWayland(struct wl_display* display, NativeDisplayOwned displayOwned) 63 72 : PlatformDisplay(displayOwned) 73 , m_display(display) 64 74 { 65 initialize(display);66 75 } 67 76 … … 75 84 } 76 85 77 void PlatformDisplayWayland::initialize( wl_display* display)86 void PlatformDisplayWayland::initialize() 78 87 { 79 m_display = display;80 88 if (!m_display) 81 89 return; -
trunk/Source/WebCore/platform/graphics/wayland/PlatformDisplayWayland.h
r230442 r230529 38 38 public: 39 39 static std::unique_ptr<PlatformDisplay> create(); 40 PlatformDisplayWayland(struct wl_display*, NativeDisplayOwned = NativeDisplayOwned::No); 40 static std::unique_ptr<PlatformDisplay> create(struct wl_display*); 41 41 42 virtual ~PlatformDisplayWayland(); 42 43 … … 48 49 static const struct wl_registry_listener s_registryListener; 49 50 50 Type type() const override{ return PlatformDisplay::Type::Wayland; }51 Type type() const final { return PlatformDisplay::Type::Wayland; } 51 52 52 53 protected: 53 PlatformDisplayWayland() = default; 54 void initialize(struct wl_display*); 54 PlatformDisplayWayland(struct wl_display*, NativeDisplayOwned); 55 56 void initialize(); 55 57 56 58 virtual void registryGlobal(const char* interface, uint32_t name); -
trunk/Source/WebCore/platform/graphics/win/PlatformDisplayWin.h
r197563 r230529 34 34 35 35 class PlatformDisplayWin final : public PlatformDisplay { 36 public: 37 static std::unique_ptr<PlatformDisplayWin> create() 38 { 39 return std::unique_ptr<PlatformDisplayWin>(new PlatformDisplayWin()); 40 } 41 42 virtual ~PlatformDisplayWin() = default; 43 36 44 private: 45 PlatformDisplayWin() 46 : PlatformDisplay(NativeDisplayOwned::No) 47 { 48 } 49 37 50 Type type() const override { return PlatformDisplay::Type::Windows; } 38 51 }; -
trunk/Source/WebCore/platform/graphics/wpe/PlatformDisplayWPE.cpp
r224412 r230529 38 38 namespace WebCore { 39 39 40 PlatformDisplayWPE::PlatformDisplayWPE() = default; 40 std::unique_ptr<PlatformDisplayWPE> PlatformDisplayWPE::create() 41 { 42 return std::unique_ptr<PlatformDisplayWPE>(new PlatformDisplayWPE()); 43 } 44 45 PlatformDisplayWPE::PlatformDisplayWPE() 46 : PlatformDisplay(NativeDisplayOwned::No) 47 { 48 } 41 49 42 50 PlatformDisplayWPE::~PlatformDisplayWPE() -
trunk/Source/WebCore/platform/graphics/wpe/PlatformDisplayWPE.h
r217208 r230529 36 36 class PlatformDisplayWPE final : public PlatformDisplay { 37 37 public: 38 PlatformDisplayWPE(); 38 static std::unique_ptr<PlatformDisplayWPE> create(); 39 39 40 virtual ~PlatformDisplayWPE(); 40 41 … … 44 45 45 46 private: 47 PlatformDisplayWPE(); 48 46 49 Type type() const override { return PlatformDisplay::Type::WPE; } 47 50 -
trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.cpp
r211145 r230529 49 49 return nullptr; 50 50 51 return std::make_unique<PlatformDisplayX11>(display, NativeDisplayOwned::Yes); 51 return std::unique_ptr<PlatformDisplayX11>(new PlatformDisplayX11(display, NativeDisplayOwned::Yes)); 52 } 53 54 std::unique_ptr<PlatformDisplay> PlatformDisplayX11::create(Display* display) 55 { 56 return std::unique_ptr<PlatformDisplayX11>(new PlatformDisplayX11(display, NativeDisplayOwned::No)); 52 57 } 53 58 -
trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.h
r211145 r230529 39 39 public: 40 40 static std::unique_ptr<PlatformDisplay> create(); 41 PlatformDisplayX11(Display*, NativeDisplayOwned = NativeDisplayOwned::No); 41 static std::unique_ptr<PlatformDisplay> create(Display*); 42 42 43 virtual ~PlatformDisplayX11(); 43 44 … … 47 48 48 49 private: 50 PlatformDisplayX11(Display*, NativeDisplayOwned); 51 49 52 Type type() const override { return PlatformDisplay::Type::X11; } 50 53 -
trunk/Source/WebKit/ChangeLog
r230528 r230529 1 2018-04-11 Michael Catanzaro <mcatanzaro@igalia.com> 2 3 [GTK] WaylandCompositorDisplay leaks its wl_display 4 https://bugs.webkit.org/show_bug.cgi?id=184406 5 6 Reviewed by Carlos Garcia Campos. 7 8 Since we allocate our own wl_display here, need to chain up to the parent constructor 9 passing NativeDisplayOwned::Yes, or it won't ever be released. Move the initialize call to 10 the create function to ensure it's called after the constructor completes. 11 12 * WebProcess/gtk/WaylandCompositorDisplay.cpp: 13 (WebKit::WaylandCompositorDisplay::create): Fix a log message (drive-by). 14 (WebKit::WaylandCompositorDisplay::WaylandCompositorDisplay): 15 1 16 2018-04-11 Youenn Fablet <youenn@apple.com> 2 17 -
trunk/Source/WebKit/WebProcess/gtk/WaylandCompositorDisplay.cpp
r230442 r230529 45 45 struct wl_display* display = wl_display_connect(displayName.utf8().data()); 46 46 if (!display) { 47 WTFLogAlways(" PlatformDisplayWaylandinitialization: failed to connect to the Wayland display: %s", displayName.utf8().data());47 WTFLogAlways("WaylandCompositorDisplay initialization: failed to connect to the Wayland display: %s", displayName.utf8().data()); 48 48 return nullptr; 49 49 } 50 50 51 return std::unique_ptr<WaylandCompositorDisplay>(new WaylandCompositorDisplay(display)); 51 auto compositorDisplay = std::unique_ptr<WaylandCompositorDisplay>(new WaylandCompositorDisplay(display)); 52 compositorDisplay->initialize(); 53 return compositorDisplay; 52 54 } 53 55 … … 62 64 63 65 WaylandCompositorDisplay::WaylandCompositorDisplay(struct wl_display* display) 66 : PlatformDisplayWayland(display, NativeDisplayOwned::Yes) 64 67 { 65 initialize(display);66 68 PlatformDisplay::setSharedDisplayForCompositing(*this); 67 69 }
Note: See TracChangeset
for help on using the changeset viewer.