| Differences between
and this patch
- a/Source/WebKit2/ChangeLog +34 lines
Lines 1-3 a/Source/WebKit2/ChangeLog_sec1
1
2014-02-25  Carlos Garcia Campos  <cgarcia@igalia.com>
2
3
        [GTK][WK2] Blocks when fetching plugins information
4
        https://bugs.webkit.org/show_bug.cgi?id=115650
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Use a persistent cache to store the plugins metadata to avoid
9
        having to load all the plugins everytime a plugin is used for the
10
        first time.
11
12
        * GNUmakefile.am:
13
        * GNUmakefile.list.am:
14
        * PlatformGTK.cmake:
15
        * Shared/Plugins/Netscape/NetscapePluginModule.h:
16
        * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
17
        (WebKit::NetscapePluginModule::parseMIMEDescription): Make this
18
        method public.
19
        (WebKit::NetscapePluginModule::buildMIMEDescription): Added this
20
        helper to build the MIME description string.
21
        * UIProcess/Plugins/gtk/PluginInfoCache.cpp: Added.
22
        (WebKit::PluginInfoCache::shared):
23
        (WebKit::PluginInfoCache::PluginInfoCache):
24
        (WebKit::PluginInfoCache::~PluginInfoCache):
25
        (WebKit::PluginInfoCache::saveToFileIdleCallback):
26
        (WebKit::PluginInfoCache::saveToFile):
27
        (WebKit::PluginInfoCache::getPluginInfo):
28
        (WebKit::PluginInfoCache::updatePluginInfo):
29
        * UIProcess/Plugins/gtk/PluginInfoCache.h: Added.
30
        * UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp:
31
        (WebKit::PluginInfoStore::getPluginInfo): Check first if we have
32
        metadata of the plugin in the cache and update the cache if we
33
        loaded the plugin to get its metadata.
34
1
2014-02-17  Carlos Garcia Campos  <cgarcia@igalia.com>
35
2014-02-17  Carlos Garcia Campos  <cgarcia@igalia.com>
2
36
3
        Unreviewed. Fix make distcheck.
37
        Unreviewed. Fix make distcheck.
- a/Source/WebKit2/GNUmakefile.am +1 lines
Lines 126-131 libwebkit2gtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CPP a/Source/WebKit2/GNUmakefile.am_sec1
126
	-I$(srcdir)/Source/WebKit2/UIProcess/Network/CustomProtocols/soup \
126
	-I$(srcdir)/Source/WebKit2/UIProcess/Network/CustomProtocols/soup \
127
	-I$(srcdir)/Source/WebKit2/UIProcess/Notifications \
127
	-I$(srcdir)/Source/WebKit2/UIProcess/Notifications \
128
	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins \
128
	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins \
129
	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/gtk \
129
	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/unix \
130
	-I$(srcdir)/Source/WebKit2/UIProcess/Plugins/unix \
130
	-I$(srcdir)/Source/WebKit2/UIProcess/Storage \
131
	-I$(srcdir)/Source/WebKit2/UIProcess/Storage \
131
	-I$(srcdir)/Source/WebKit2/UIProcess/soup \
132
	-I$(srcdir)/Source/WebKit2/UIProcess/soup \
- a/Source/WebKit2/GNUmakefile.list.am +2 lines
Lines 870-875 webkit2_sources += \ a/Source/WebKit2/GNUmakefile.list.am_sec1
870
	Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h \
870
	Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h \
871
	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h \
871
	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h \
872
	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp \
872
	Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp \
873
	Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp \
874
	Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h \
873
	Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp \
875
	Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp \
874
	Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp \
876
	Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp \
875
	Source/WebKit2/UIProcess/ProcessModel.h \
877
	Source/WebKit2/UIProcess/ProcessModel.h \
- a/Source/WebKit2/PlatformGTK.cmake +3 lines
Lines 246-251 list(APPEND WebKit2_SOURCES a/Source/WebKit2/PlatformGTK.cmake_sec1
246
    UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp
246
    UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp
247
    UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp
247
    UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp
248
248
249
    UIProcess/Plugins/gtk/PluginInfoCache.cpp
250
249
    UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
251
    UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
250
    UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
252
    UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
251
253
Lines 407-412 list(APPEND WebKit2_INCLUDE_DIRECTORIES a/Source/WebKit2/PlatformGTK.cmake_sec2
407
    "${WEBKIT2_DIR}/UIProcess/API/cpp/gtk"
409
    "${WEBKIT2_DIR}/UIProcess/API/cpp/gtk"
408
    "${WEBKIT2_DIR}/UIProcess/API/gtk"
410
    "${WEBKIT2_DIR}/UIProcess/API/gtk"
409
    "${WEBKIT2_DIR}/UIProcess/Network/CustomProtocols/soup"
411
    "${WEBKIT2_DIR}/UIProcess/Network/CustomProtocols/soup"
412
    "${WEBKIT2_DIR}/UIProcess/Plugins/gtk"
410
    "${WEBKIT2_DIR}/UIProcess/gtk"
413
    "${WEBKIT2_DIR}/UIProcess/gtk"
411
    "${WEBKIT2_DIR}/UIProcess/soup"
414
    "${WEBKIT2_DIR}/UIProcess/soup"
412
    "${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk"
415
    "${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/gtk"
- a/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h +6 lines
Lines 35-40 a/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h_sec1
35
#include <wtf/RefCounted.h>
35
#include <wtf/RefCounted.h>
36
#include <wtf/text/WTFString.h>
36
#include <wtf/text/WTFString.h>
37
37
38
namespace WebCore {
39
struct MimeClassInfo;
40
}
41
38
namespace WebKit {
42
namespace WebKit {
39
43
40
class RawPluginMetaData;
44
class RawPluginMetaData;
Lines 67-72 public: a/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h_sec2
67
71
68
#if PLUGIN_ARCHITECTURE(X11)
72
#if PLUGIN_ARCHITECTURE(X11)
69
    static bool scanPlugin(const String& pluginPath);
73
    static bool scanPlugin(const String& pluginPath);
74
    static void parseMIMEDescription(const String& mimeDescription, Vector<WebCore::MimeClassInfo>& result);
75
    static String buildMIMEDescription(const Vector<WebCore::MimeClassInfo>&);
70
#endif
76
#endif
71
77
72
private:
78
private:
- a/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp -1 / +28 lines
Lines 36-41 a/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp_sec1
36
#include <sys/stat.h>
36
#include <sys/stat.h>
37
#include <sys/types.h>
37
#include <sys/types.h>
38
#include <unistd.h>
38
#include <unistd.h>
39
#include <wtf/text/StringBuilder.h>
39
40
40
using namespace WebCore;
41
using namespace WebCore;
41
42
Lines 67-73 StdoutDevNullRedirector::~StdoutDevNullRedirector() a/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp_sec2
67
}
68
}
68
69
69
70
70
static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
71
void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
71
{
72
{
72
    ASSERT_ARG(result, result.isEmpty());
73
    ASSERT_ARG(result, result.isEmpty());
73
74
Lines 94-99 static void parseMIMEDescription(const String& mimeDescription, Vector<MimeClass a/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp_sec3
94
    }
95
    }
95
}
96
}
96
97
98
String NetscapePluginModule::buildMIMEDescription(const Vector<MimeClassInfo>& mimeDescription)
99
{
100
    StringBuilder builder;
101
102
    size_t mimeInfoCount = mimeDescription.size();
103
    for (size_t i = 0; i < mimeInfoCount; ++i) {
104
        const MimeClassInfo& mimeInfo = mimeDescription[i];
105
        builder.append(mimeInfo.type);
106
        builder.append(':');
107
108
        size_t extensionsCount = mimeInfo.extensions.size();
109
        for (size_t j = 0; j < extensionsCount; ++j) {
110
            builder.append(mimeInfo.extensions[j]);
111
            if (j != extensionsCount - 1)
112
                builder.append(',');
113
        }
114
        builder.append(':');
115
116
        builder.append(mimeInfo.desc);
117
        if (i != mimeInfoCount - 1)
118
            builder.append(';');
119
    }
120
121
    return builder.toString();
122
}
123
97
bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
124
bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
98
{
125
{
99
    ASSERT(m_isInitialized);
126
    ASSERT(m_isInitialized);
- a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp +142 lines
Line 0 a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp_sec1
1
/*
2
 * Copyright (C) 2014 Igalia S.L.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "config.h"
27
#include "PluginInfoCache.h"
28
29
#if ENABLE(NETSCAPE_PLUGIN_API)
30
31
#include "NetscapePluginModule.h"
32
#include <WebCore/FileSystem.h>
33
#include <wtf/text/CString.h>
34
35
namespace WebKit {
36
37
static const unsigned gSchemaVersion = 1;
38
39
PluginInfoCache& PluginInfoCache::shared()
40
{
41
    static NeverDestroyed<PluginInfoCache> pluginInfoCache;
42
    return pluginInfoCache;
43
}
44
45
PluginInfoCache::PluginInfoCache()
46
    : m_cacheFile(g_key_file_new())
47
    , m_cachePath(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "plugins", nullptr))
48
    , m_saveToFileIdleId(0)
49
{
50
    g_key_file_load_from_file(m_cacheFile.get(), m_cachePath.get(), G_KEY_FILE_NONE, nullptr);
51
52
    if (g_key_file_has_group(m_cacheFile.get(), "schema")) {
53
        unsigned schemaVersion = static_cast<unsigned>(g_key_file_get_integer(m_cacheFile.get(), "schema", "version", nullptr));
54
        if (schemaVersion == gSchemaVersion)
55
            return;
56
57
        // Cache file using an old schema, create a new empty file.
58
        m_cacheFile.reset(g_key_file_new());
59
    }
60
61
    g_key_file_set_integer(m_cacheFile.get(), "schema", "version", static_cast<unsigned>(gSchemaVersion));
62
}
63
64
PluginInfoCache::~PluginInfoCache()
65
{
66
    if (m_saveToFileIdleId) {
67
        g_source_remove(m_saveToFileIdleId);
68
        saveToFile();
69
    }
70
}
71
72
gboolean PluginInfoCache::saveToFileIdleCallback(PluginInfoCache* cache)
73
{
74
    cache->saveToFile();
75
    return FALSE;
76
}
77
78
void PluginInfoCache::saveToFile()
79
{
80
    m_saveToFileIdleId = 0;
81
82
    gsize dataLength;
83
    GUniquePtr<char> data(g_key_file_to_data(m_cacheFile.get(), &dataLength, nullptr));
84
    if (!data)
85
        return;
86
87
    g_file_set_contents(m_cachePath.get(), data.get(), dataLength, nullptr);
88
}
89
90
bool PluginInfoCache::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
91
{
92
    CString pluginGroup = pluginPath.utf8();
93
    if (!g_key_file_has_group(m_cacheFile.get(), pluginGroup.data()))
94
        return false;
95
96
    time_t lastModified;
97
    if (!WebCore::getFileModificationTime(pluginPath, lastModified))
98
        return false;
99
    time_t cachedLastModified = static_cast<time_t>(g_key_file_get_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", nullptr));
100
    if (lastModified != cachedLastModified)
101
        return false;
102
103
    plugin.path = pluginPath;
104
    plugin.info.file = WebCore::pathGetFileName(pluginPath);
105
106
    GUniquePtr<char> stringValue(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "name", nullptr));
107
    plugin.info.name = String::fromUTF8(stringValue.get());
108
109
    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "description", nullptr));
110
    plugin.info.desc = String::fromUTF8(stringValue.get());
111
112
    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", nullptr));
113
    NetscapePluginModule::parseMIMEDescription(String::fromUTF8(stringValue.get()), plugin.info.mimes);
114
115
    return true;
116
}
117
118
void PluginInfoCache::updatePluginInfo(const String& pluginPath, const PluginModuleInfo& plugin)
119
{
120
    time_t lastModified;
121
    if (!WebCore::getFileModificationTime(pluginPath, lastModified))
122
        return;
123
124
    CString pluginGroup = pluginPath.utf8();
125
    g_key_file_set_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", static_cast<guint64>(lastModified));
126
    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "name", plugin.info.name.utf8().data());
127
    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "description", plugin.info.desc.utf8().data());
128
129
    String mimeDescription = NetscapePluginModule::buildMIMEDescription(plugin.info.mimes);
130
    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", mimeDescription.utf8().data());
131
132
    // Save the cache file in an idle to make sure it happens in the main thread and
133
    // it's done only once when this is called multiple times in a very short time.
134
    if (m_saveToFileIdleId)
135
        return;
136
137
    m_saveToFileIdleId = g_idle_add(reinterpret_cast<GSourceFunc>(PluginInfoCache::saveToFileIdleCallback), this);
138
}
139
140
} // namespace WebKit
141
142
#endif // ENABLE(NETSCAPE_PLUGIN_API)
- a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h +62 lines
Line 0 a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h_sec1
1
/*
2
 * Copyright (C) 2014 Igalia S.L.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#ifndef PluginInfoCache_h
27
#define PluginInfoCache_h
28
29
#if ENABLE(NETSCAPE_PLUGIN_API)
30
31
#include "PluginModuleInfo.h"
32
#include <wtf/NeverDestroyed.h>
33
#include <wtf/gobject/GUniquePtr.h>
34
35
namespace WebKit {
36
37
class PluginInfoCache {
38
    WTF_MAKE_NONCOPYABLE(PluginInfoCache);
39
    friend class NeverDestroyed<PluginInfoCache>;
40
public:
41
    static PluginInfoCache& shared();
42
43
    bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
44
    void updatePluginInfo(const String& pluginPath, const PluginModuleInfo&);
45
46
private:
47
    PluginInfoCache();
48
    ~PluginInfoCache();
49
50
    void saveToFile();
51
    static gboolean saveToFileIdleCallback(PluginInfoCache*);
52
53
    GUniquePtr<GKeyFile> m_cacheFile;
54
    GUniquePtr<char> m_cachePath;
55
    unsigned m_saveToFileIdleId;
56
};
57
58
} // namespace WebKit
59
60
#endif // ENABLE(NETSCAPE_PLUGIN_API)
61
62
#endif // PluginInfoCache_h
- a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp +15 lines
Lines 35-40 a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp_sec1
35
#include "PluginDatabase.h"
35
#include "PluginDatabase.h"
36
#include <WebCore/FileSystem.h>
36
#include <WebCore/FileSystem.h>
37
37
38
#if PLATFORM(GTK)
39
#include "PluginInfoCache.h"
40
#endif
41
38
using namespace WebCore;
42
using namespace WebCore;
39
43
40
namespace WebKit {
44
namespace WebKit {
Lines 98-104 Vector<String> PluginInfoStore::individualPluginPaths() a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp_sec2
98
102
99
bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
103
bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
100
{
104
{
105
#if PLATFORM(GTK)
106
    if (PluginInfoCache::shared().getPluginInfo(pluginPath, plugin))
107
        return true;
108
109
    if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) {
110
        PluginInfoCache::shared().updatePluginInfo(pluginPath, plugin);
111
        return true;
112
    }
113
    return false;
114
#else
101
    return NetscapePluginModule::getPluginInfo(pluginPath, plugin);
115
    return NetscapePluginModule::getPluginInfo(pluginPath, plugin);
116
#endif
102
}
117
}
103
118
104
bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/)
119
bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/)

Return to Bug 115650