Title: [164808] trunk/Source/WebKit2
Revision
164808
Author
[email protected]
Date
2014-02-27 09:59:16 -0800 (Thu, 27 Feb 2014)

Log Message

[GTK][WK2] Blocks when fetching plugins information
https://bugs.webkit.org/show_bug.cgi?id=115650

Reviewed by Gustavo Noronha Silva.

Use a persistent cache to store the plugins metadata to avoid
having to load all the plugins everytime a plugin is used for the
first time.

* GNUmakefile.am:
* GNUmakefile.list.am:
* PlatformGTK.cmake:
* Shared/Plugins/Netscape/NetscapePluginModule.h:
* Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
(WebKit::NetscapePluginModule::parseMIMEDescription): Make this
method public.
(WebKit::NetscapePluginModule::buildMIMEDescription): Added this
helper to build the MIME description string.
* UIProcess/Plugins/gtk/PluginInfoCache.cpp: Added.
(WebKit::PluginInfoCache::shared):
(WebKit::PluginInfoCache::PluginInfoCache):
(WebKit::PluginInfoCache::~PluginInfoCache):
(WebKit::PluginInfoCache::saveToFileIdleCallback):
(WebKit::PluginInfoCache::saveToFile):
(WebKit::PluginInfoCache::getPluginInfo):
(WebKit::PluginInfoCache::updatePluginInfo):
* UIProcess/Plugins/gtk/PluginInfoCache.h: Added.
* UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp:
(WebKit::PluginInfoStore::getPluginInfo): Check first if we have
metadata of the plugin in the cache and update the cache if we
loaded the plugin to get its metadata.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (164807 => 164808)


--- trunk/Source/WebKit2/ChangeLog	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/ChangeLog	2014-02-27 17:59:16 UTC (rev 164808)
@@ -1,3 +1,37 @@
+2014-02-27  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WK2] Blocks when fetching plugins information
+        https://bugs.webkit.org/show_bug.cgi?id=115650
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Use a persistent cache to store the plugins metadata to avoid
+        having to load all the plugins everytime a plugin is used for the
+        first time.
+
+        * GNUmakefile.am:
+        * GNUmakefile.list.am:
+        * PlatformGTK.cmake:
+        * Shared/Plugins/Netscape/NetscapePluginModule.h:
+        * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
+        (WebKit::NetscapePluginModule::parseMIMEDescription): Make this
+        method public.
+        (WebKit::NetscapePluginModule::buildMIMEDescription): Added this
+        helper to build the MIME description string.
+        * UIProcess/Plugins/gtk/PluginInfoCache.cpp: Added.
+        (WebKit::PluginInfoCache::shared):
+        (WebKit::PluginInfoCache::PluginInfoCache):
+        (WebKit::PluginInfoCache::~PluginInfoCache):
+        (WebKit::PluginInfoCache::saveToFileIdleCallback):
+        (WebKit::PluginInfoCache::saveToFile):
+        (WebKit::PluginInfoCache::getPluginInfo):
+        (WebKit::PluginInfoCache::updatePluginInfo):
+        * UIProcess/Plugins/gtk/PluginInfoCache.h: Added.
+        * UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp:
+        (WebKit::PluginInfoStore::getPluginInfo): Check first if we have
+        metadata of the plugin in the cache and update the cache if we
+        loaded the plugin to get its metadata.
+
 2014-02-27  Ryan Lortie  <[email protected]>
 
         need to #include <libgen.h> for basename

Modified: trunk/Source/WebKit2/GNUmakefile.am (164807 => 164808)


--- trunk/Source/WebKit2/GNUmakefile.am	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/GNUmakefile.am	2014-02-27 17:59:16 UTC (rev 164808)
@@ -126,6 +126,7 @@
 	-I$(srcdir)/Source/WebKit2/UIProcess/Network/CustomProtocols/soup \
 	-I$(srcdir)/Source/WebKit2/UIProcess/Notifications \
 	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins \
+	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/gtk \
 	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/unix \
 	-I$(srcdir)/Source/WebKit2/UIProcess/Storage \
 	-I$(srcdir)/Source/WebKit2/UIProcess/soup \

Modified: trunk/Source/WebKit2/GNUmakefile.list.am (164807 => 164808)


--- trunk/Source/WebKit2/GNUmakefile.list.am	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/GNUmakefile.list.am	2014-02-27 17:59:16 UTC (rev 164808)
@@ -866,6 +866,8 @@
 	Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h \
 	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h \
 	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp \
+	Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp \
+	Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h \
 	Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp \
 	Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp \
 	Source/WebKit2/UIProcess/ProcessModel.h \

Modified: trunk/Source/WebKit2/PlatformGTK.cmake (164807 => 164808)


--- trunk/Source/WebKit2/PlatformGTK.cmake	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/PlatformGTK.cmake	2014-02-27 17:59:16 UTC (rev 164808)
@@ -248,6 +248,8 @@
     UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp
     UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp
 
+    UIProcess/Plugins/gtk/PluginInfoCache.cpp
+
     UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
     UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
 
@@ -409,6 +411,7 @@
     "${WEBKIT2_DIR}/UIProcess/API/cpp/gtk"
     "${WEBKIT2_DIR}/UIProcess/API/gtk"
     "${WEBKIT2_DIR}/UIProcess/Network/CustomProtocols/soup"
+    "${WEBKIT2_DIR}/UIProcess/Plugins/gtk"
     "${WEBKIT2_DIR}/UIProcess/gtk"
     "${WEBKIT2_DIR}/UIProcess/soup"
     "${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk"

Modified: trunk/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h (164807 => 164808)


--- trunk/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h	2014-02-27 17:59:16 UTC (rev 164808)
@@ -35,6 +35,10 @@
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
+namespace WebCore {
+struct MimeClassInfo;
+}
+
 namespace WebKit {
 
 struct RawPluginMetaData;
@@ -67,6 +71,8 @@
 
 #if PLUGIN_ARCHITECTURE(X11)
     static bool scanPlugin(const String& pluginPath);
+    static void parseMIMEDescription(const String& mimeDescription, Vector<WebCore::MimeClassInfo>& result);
+    static String buildMIMEDescription(const Vector<WebCore::MimeClassInfo>&);
 #endif
 
 private:

Modified: trunk/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp (164807 => 164808)


--- trunk/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp	2014-02-27 17:59:16 UTC (rev 164808)
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <wtf/text/StringBuilder.h>
 
 using namespace WebCore;
 
@@ -67,7 +68,7 @@
 }
 
 
-static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
+void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
 {
     ASSERT_ARG(result, result.isEmpty());
 
@@ -94,6 +95,32 @@
     }
 }
 
+String NetscapePluginModule::buildMIMEDescription(const Vector<MimeClassInfo>& mimeDescription)
+{
+    StringBuilder builder;
+
+    size_t mimeInfoCount = mimeDescription.size();
+    for (size_t i = 0; i < mimeInfoCount; ++i) {
+        const MimeClassInfo& mimeInfo = mimeDescription[i];
+        builder.append(mimeInfo.type);
+        builder.append(':');
+
+        size_t extensionsCount = mimeInfo.extensions.size();
+        for (size_t j = 0; j < extensionsCount; ++j) {
+            builder.append(mimeInfo.extensions[j]);
+            if (j != extensionsCount - 1)
+                builder.append(',');
+        }
+        builder.append(':');
+
+        builder.append(mimeInfo.desc);
+        if (i != mimeInfoCount - 1)
+            builder.append(';');
+    }
+
+    return builder.toString();
+}
+
 bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
 {
     ASSERT(m_isInitialized);

Added: trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp (0 => 164808)


--- trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp	2014-02-27 17:59:16 UTC (rev 164808)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginInfoCache.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePluginModule.h"
+#include <WebCore/FileSystem.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+static const unsigned gSchemaVersion = 1;
+
+PluginInfoCache& PluginInfoCache::shared()
+{
+    static NeverDestroyed<PluginInfoCache> pluginInfoCache;
+    return pluginInfoCache;
+}
+
+PluginInfoCache::PluginInfoCache()
+    : m_cacheFile(g_key_file_new())
+    , m_cachePath(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "plugins", nullptr))
+    , m_saveToFileIdleId(0)
+{
+    g_key_file_load_from_file(m_cacheFile.get(), m_cachePath.get(), G_KEY_FILE_NONE, nullptr);
+
+    if (g_key_file_has_group(m_cacheFile.get(), "schema")) {
+        unsigned schemaVersion = static_cast<unsigned>(g_key_file_get_integer(m_cacheFile.get(), "schema", "version", nullptr));
+        if (schemaVersion == gSchemaVersion)
+            return;
+
+        // Cache file using an old schema, create a new empty file.
+        m_cacheFile.reset(g_key_file_new());
+    }
+
+    g_key_file_set_integer(m_cacheFile.get(), "schema", "version", static_cast<unsigned>(gSchemaVersion));
+}
+
+PluginInfoCache::~PluginInfoCache()
+{
+    if (m_saveToFileIdleId) {
+        g_source_remove(m_saveToFileIdleId);
+        saveToFile();
+    }
+}
+
+gboolean PluginInfoCache::saveToFileIdleCallback(PluginInfoCache* cache)
+{
+    cache->saveToFile();
+    return FALSE;
+}
+
+void PluginInfoCache::saveToFile()
+{
+    std::lock_guard<std::mutex> lock(m_mutex);
+    m_saveToFileIdleId = 0;
+
+    gsize dataLength;
+    GUniquePtr<char> data(g_key_file_to_data(m_cacheFile.get(), &dataLength, nullptr));
+    if (!data)
+        return;
+
+    g_file_set_contents(m_cachePath.get(), data.get(), dataLength, nullptr);
+}
+
+bool PluginInfoCache::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
+{
+    CString pluginGroup = pluginPath.utf8();
+    if (!g_key_file_has_group(m_cacheFile.get(), pluginGroup.data()))
+        return false;
+
+    time_t lastModified;
+    if (!WebCore::getFileModificationTime(pluginPath, lastModified))
+        return false;
+    time_t cachedLastModified = static_cast<time_t>(g_key_file_get_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", nullptr));
+    if (lastModified != cachedLastModified)
+        return false;
+
+    plugin.path = pluginPath;
+    plugin.info.file = WebCore::pathGetFileName(pluginPath);
+
+    GUniquePtr<char> stringValue(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "name", nullptr));
+    plugin.info.name = String::fromUTF8(stringValue.get());
+
+    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "description", nullptr));
+    plugin.info.desc = String::fromUTF8(stringValue.get());
+
+    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", nullptr));
+    NetscapePluginModule::parseMIMEDescription(String::fromUTF8(stringValue.get()), plugin.info.mimes);
+
+    return true;
+}
+
+void PluginInfoCache::updatePluginInfo(const String& pluginPath, const PluginModuleInfo& plugin)
+{
+    time_t lastModified;
+    if (!WebCore::getFileModificationTime(pluginPath, lastModified))
+        return;
+
+    CString pluginGroup = pluginPath.utf8();
+    g_key_file_set_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", static_cast<guint64>(lastModified));
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "name", plugin.info.name.utf8().data());
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "description", plugin.info.desc.utf8().data());
+
+    String mimeDescription = NetscapePluginModule::buildMIMEDescription(plugin.info.mimes);
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", mimeDescription.utf8().data());
+
+    // Save the cache file in an idle to make sure it happens in the main thread and
+    // it's done only once when this is called multiple times in a very short time.
+    std::lock_guard<std::mutex> lock(m_mutex);
+    if (m_saveToFileIdleId)
+        return;
+
+    m_saveToFileIdleId = g_idle_add(reinterpret_cast<GSourceFunc>(PluginInfoCache::saveToFileIdleCallback), this);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)

Added: trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h (0 => 164808)


--- trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h	2014-02-27 17:59:16 UTC (rev 164808)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginInfoCache_h
+#define PluginInfoCache_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+#include <mutex>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/gobject/GUniquePtr.h>
+
+namespace WebKit {
+
+class PluginInfoCache {
+    WTF_MAKE_NONCOPYABLE(PluginInfoCache);
+    friend class NeverDestroyed<PluginInfoCache>;
+public:
+    static PluginInfoCache& shared();
+
+    bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
+    void updatePluginInfo(const String& pluginPath, const PluginModuleInfo&);
+
+private:
+    PluginInfoCache();
+    ~PluginInfoCache();
+
+    void saveToFile();
+    static gboolean saveToFileIdleCallback(PluginInfoCache*);
+
+    GUniquePtr<GKeyFile> m_cacheFile;
+    GUniquePtr<char> m_cachePath;
+    unsigned m_saveToFileIdleId;
+    std::mutex m_mutex;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginInfoCache_h

Modified: trunk/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp (164807 => 164808)


--- trunk/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp	2014-02-27 17:49:45 UTC (rev 164807)
+++ trunk/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp	2014-02-27 17:59:16 UTC (rev 164808)
@@ -35,6 +35,10 @@
 #include "PluginDatabase.h"
 #include <WebCore/FileSystem.h>
 
+#if PLATFORM(GTK)
+#include "PluginInfoCache.h"
+#endif
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -98,7 +102,18 @@
 
 bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
 {
+#if PLATFORM(GTK)
+    if (PluginInfoCache::shared().getPluginInfo(pluginPath, plugin))
+        return true;
+
+    if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) {
+        PluginInfoCache::shared().updatePluginInfo(pluginPath, plugin);
+        return true;
+    }
+    return false;
+#else
     return NetscapePluginModule::getPluginInfo(pluginPath, plugin);
+#endif
 }
 
 bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to