Changeset 31465 in webkit


Ignore:
Timestamp:
Mar 31, 2008 9:55:48 AM (16 years ago)
Author:
Adam Roben
Message:

Separate filesystem crawling from PluginPackage instantiation

Part of Bug 18208: Acid3 test 65 takes >33ms due to plugin refreshing
on Windows
<http://bugs.webkit.org/show_bug.cgi?id=18208>

refresh() is now the only place where PluginPackages are instantiated.
refresh() now asks for a set of plugins that no longer exist on disk,
and the set of all plugin files in our plugin directories. Using these
two sets we can update our instantiated plugins without copying any
HashSets. The code in refresh() and in the platform-specific methods
to crawl the filesystem is now quite a bit simpler.

PluginDatabase now stores both a PluginSet and a HashMap that maps
plugin paths to PluginPackages. This allows us to quickly determine
whether we already have a PluginPackage instantiated for a particular
path. The new add/remove methods handle the modification of these two
collections.

A nice side effect of all this is that refresh() no longer copies any
HashSets.

Reviewed by Mitz Pettel.

  • plugins/PluginDatabase.cpp: (WebCore::PluginDatabase::refresh): Unload any plugins that have been deleted from disk, and add any plugins that either weren't installed last time, or have changed since last time. (WebCore::PluginDatabase::getDeletedPlugins): Added. (WebCore::PluginDatabase::add): Added. Returns whether or not the PluginPackage was actually added to the database (duplicates won't be added). (WebCore::PluginDatabase::remove): Added.
  • plugins/PluginDatabase.h:
  • plugins/PluginPackage.h: (WebCore::PluginPackage::path): Added. (WebCore::PluginPackage::lastModified): Added.
  • plugins/gtk/PluginDatabaseGtk.cpp: (WebCore::PluginDatabase::getPluginPathsInDirectories): Renamed from getPluginsInDirectories. Now fills a HashSet of Strings instead of instantiated PluginPackages.
  • plugins/win/PluginDatabaseWin.cpp: (WebCore::addPluginPathsFromRegistry): Ditto. (WebCore::PluginDatabase::getPluginPathsInDirectories): Ditto.
Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r31464 r31465  
     12008-03-29  Adam Roben  <aroben@apple.com>
     2
     3        Separate filesystem crawling from PluginPackage instantiation
     4
     5        Part of Bug 18208: Acid3 test 65 takes >33ms due to plugin refreshing
     6        on Windows
     7        <http://bugs.webkit.org/show_bug.cgi?id=18208>
     8
     9        refresh() is now the only place where PluginPackages are instantiated.
     10        refresh() now asks for a set of plugins that no longer exist on disk,
     11        and the set of all plugin files in our plugin directories. Using these
     12        two sets we can update our instantiated plugins without copying any
     13        HashSets. The code in refresh() and in the platform-specific methods
     14        to crawl the filesystem is now quite a bit simpler.
     15
     16        PluginDatabase now stores both a PluginSet and a HashMap that maps
     17        plugin paths to PluginPackages. This allows us to quickly determine
     18        whether we already have a PluginPackage instantiated for a particular
     19        path. The new add/remove methods handle the modification of these two
     20        collections.
     21
     22        A nice side effect of all this is that refresh() no longer copies any
     23        HashSets.
     24
     25        Reviewed by Mitz Pettel.
     26
     27        * plugins/PluginDatabase.cpp:
     28        (WebCore::PluginDatabase::refresh): Unload any plugins that have been
     29        deleted from disk, and add any plugins that either weren't installed
     30        last time, or have changed since last time.
     31        (WebCore::PluginDatabase::getDeletedPlugins): Added.
     32        (WebCore::PluginDatabase::add): Added. Returns whether or not the
     33        PluginPackage was actually added to the database (duplicates won't be
     34        added).
     35        (WebCore::PluginDatabase::remove): Added.
     36        * plugins/PluginDatabase.h:
     37        * plugins/PluginPackage.h:
     38        (WebCore::PluginPackage::path): Added.
     39        (WebCore::PluginPackage::lastModified): Added.
     40        * plugins/gtk/PluginDatabaseGtk.cpp:
     41        (WebCore::PluginDatabase::getPluginPathsInDirectories): Renamed from
     42        getPluginsInDirectories. Now fills a HashSet of Strings instead of
     43        instantiated PluginPackages.
     44        * plugins/win/PluginDatabaseWin.cpp:
     45        (WebCore::addPluginPathsFromRegistry): Ditto.
     46        (WebCore::PluginDatabase::getPluginPathsInDirectories): Ditto.
     47
    1482008-03-29  Adam Roben  <aroben@apple.com>
    249
  • trunk/WebCore/plugins/PluginDatabase.cpp

    r31464 r31465  
    6666bool PluginDatabase::refresh()
    6767{   
    68     PluginSet newPlugins;
    69 
    7068    bool pluginSetChanged = false;
    71 
    72     // Create a new set of plugins
    73     getPluginsInDirectories(newPlugins);
    7469
    7570    if (!m_plugins.isEmpty()) {
    7671        m_registeredMIMETypes.clear();
    7772
    78         PluginSet pluginsToUnload = m_plugins;
    79 
    80         PluginSet::const_iterator end = newPlugins.end();
    81         for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
    82             pluginsToUnload.remove(*it);
    83 
    84         end = m_plugins.end();
    85         for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it)
    86             newPlugins.remove(*it);
     73        PluginSet pluginsToUnload;
     74        getDeletedPlugins(pluginsToUnload);
    8775
    8876        // Unload plugins
    89         end = pluginsToUnload.end();
     77        PluginSet::const_iterator end = pluginsToUnload.end();
    9078        for (PluginSet::const_iterator it = pluginsToUnload.begin(); it != end; ++it)
    91             m_plugins.remove(*it);
    92 
    93         // Add new plugins
    94         end = newPlugins.end();
    95         for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
    96             m_plugins.add(*it);
    97 
    98         pluginSetChanged = !pluginsToUnload.isEmpty() || !newPlugins.isEmpty();
    99     } else {
    100         m_plugins = newPlugins;
    101         PluginSet::const_iterator end = newPlugins.end();
    102         for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
    103             m_plugins.add(*it);
    104 
    105         pluginSetChanged = !newPlugins.isEmpty();
     79            remove(it->get());
     80
     81        pluginSetChanged = !pluginsToUnload.isEmpty();
     82    }
     83
     84    HashSet<String> paths;
     85    getPluginPathsInDirectories(paths);
     86
     87    HashSet<String>::const_iterator pathsEnd = paths.end();
     88    for (HashSet<String>::const_iterator it = paths.begin(); it != pathsEnd; ++it) {
     89        time_t lastModified;
     90        if (!getFileModificationTime(*it, lastModified))
     91            continue;
     92
     93        if (RefPtr<PluginPackage> oldPackage = m_pluginsByPath.get(*it)) {
     94            if (oldPackage->lastModified() == lastModified)
     95                continue;
     96            remove(oldPackage.get());
     97        }
     98
     99        if (add(PluginPackage::createPackage(*it, lastModified)))
     100            pluginSetChanged = true;
    106101    }
    107102
     
    223218}
    224219
    225 }
     220void PluginDatabase::getDeletedPlugins(PluginSet& plugins) const
     221{
     222    PluginSet::const_iterator end = m_plugins.end();
     223    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
     224        if (!fileExists((*it)->path()))
     225            plugins.add(*it);
     226    }
     227}
     228
     229bool PluginDatabase::add(PassRefPtr<PluginPackage> prpPackage)
     230{
     231    RefPtr<PluginPackage> package = prpPackage;
     232
     233    if (!m_plugins.add(package).second)
     234        return false;
     235
     236    m_pluginsByPath.add(package->path(), package);
     237    return true;
     238}
     239
     240void PluginDatabase::remove(PluginPackage* package)
     241{
     242    m_plugins.remove(package);
     243    m_pluginsByPath.remove(package->path());
     244}
     245
     246}
  • trunk/WebCore/plugins/PluginDatabase.h

    r31464 r31465  
    6060    private:
    6161        void setPluginDirectories(const Vector<String>& directories) { m_pluginDirectories = directories; }
    62         void getPluginsInDirectories(PluginSet&) const;
     62
     63        void getPluginPathsInDirectories(HashSet<String>&) const;
     64        void getDeletedPlugins(PluginSet&) const;
     65
     66        // Returns whether the plugin was actually added or not (it won't be added if it's a duplicate of an existing plugin).
     67        bool add(PassRefPtr<PluginPackage>);
     68        void remove(PluginPackage*);
    6369
    6470        PluginPackage* pluginForMIMEType(const String& mimeType);
     
    7076        HashSet<String> m_registeredMIMETypes;
    7177        PluginSet m_plugins;
     78        HashMap<String, RefPtr<PluginPackage> > m_pluginsByPath;
    7279    };
    7380
  • trunk/WebCore/plugins/PluginPackage.h

    r31463 r31465  
    4848        const String& name() const { return m_name; }
    4949        const String& description() const { return m_description; }
     50        const String& path() const { return m_path; }
    5051        const String& fileName() const { return m_fileName; }
    5152        const String& parentDirectory() const { return m_parentDirectory; }
     53        time_t lastModified() const { return m_lastModified; }
    5254
    5355        const MIMEToDescriptionsMap& mimeToDescriptions() const { return m_mimeToDescriptions; }
  • trunk/WebCore/plugins/gtk/PluginDatabaseGtk.cpp

    r31464 r31465  
    3333namespace WebCore {
    3434
    35 void PluginDatabase::getPluginsInDirectories(PluginSet& plugins) const
     35void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
    3636{
    3737    // FIXME: This should be a case insensitive set.
     
    4949
    5050            gchar* filename = g_build_filename((it->utf8()).data(), name, 0);
    51             RefPtr<PluginPackage> pluginPackage = PluginPackage::createPackage(filename, time(0));
    52             if (pluginPackage)
    53                 plugins.add(pluginPackage);
     51            paths.add(filename);
    5452            g_free(filename);
    5553        }
  • trunk/WebCore/plugins/win/PluginDatabaseWin.cpp

    r31464 r31465  
    3636namespace WebCore {
    3737
    38 static inline void addPluginsFromRegistry(HKEY rootKey, PluginSet& plugins)
     38static inline void addPluginPathsFromRegistry(HKEY rootKey, HashSet<String>& paths)
    3939{
    4040    HKEY key;
     
    6363            continue;
    6464
    65         String path(pathStr, pathStrSize / sizeof(WCHAR) - 1);
    66 
    67         time_t modifiedTime;
    68         if (!getFileModificationTime(path, modifiedTime))
    69             continue;
    70 
    71         RefPtr<PluginPackage> package = PluginPackage::createPackage(path, modifiedTime);
    72 
    73         if (package)
    74             plugins.add(package);
     65        paths.add(String(pathStr, pathStrSize / sizeof(WCHAR) - 1));
    7566    }
    7667
     
    7869}
    7970
    80 void PluginDatabase::getPluginsInDirectories(PluginSet& plugins) const
     71void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
    8172{
    8273    // FIXME: This should be a case insensitive set.
     
    8677    WIN32_FIND_DATAW findFileData;
    8778
    88     RefPtr<PluginPackage> oldWMPPlugin;
    89     RefPtr<PluginPackage> newWMPPlugin;
     79    String oldWMPPluginPath;
     80    String newWMPPluginPath;
    9081
    9182    Vector<String>::const_iterator end = m_pluginDirectories.end();
     
    111102                continue;
    112103
    113             time_t modifiedTime;
    114             if (!getFileModificationTime(fullPath, modifiedTime))
    115                 continue;
    116        
    117             RefPtr<PluginPackage> pluginPackage = PluginPackage::createPackage(fullPath, modifiedTime);
    118 
    119             if (pluginPackage) {
    120                 plugins.add(pluginPackage);
    121 
    122                 if (equalIgnoringCase(filename, "npdsplay.dll"))
    123                     oldWMPPlugin = pluginPackage;
    124                 else if (equalIgnoringCase(filename, "np-mswmp.dll"))
    125                     newWMPPlugin = pluginPackage;
    126             }
     104            paths.add(fullPath);
     105
     106            if (equalIgnoringCase(filename, "npdsplay.dll"))
     107                oldWMPPluginPath = fullPath;
     108            else if (equalIgnoringCase(filename, "np-mswmp.dll"))
     109                newWMPPluginPath = fullPath;
    127110
    128111        } while (FindNextFileW(hFind, &findFileData) != 0);
     
    131114    }
    132115
    133     addPluginsFromRegistry(HKEY_LOCAL_MACHINE, plugins);
    134     addPluginsFromRegistry(HKEY_CURRENT_USER, plugins);
     116    addPluginPathsFromRegistry(HKEY_LOCAL_MACHINE, paths);
     117    addPluginPathsFromRegistry(HKEY_CURRENT_USER, paths);
    135118
    136119    // If both the old and new WMP plugin are present in the plugins set,
    137120    // we remove the old one so we don't end up choosing the old one.
    138     if (oldWMPPlugin && newWMPPlugin)
    139         plugins.remove(oldWMPPlugin);
     121    if (!oldWMPPluginPath.isEmpty() && !newWMPPluginPath.isEmpty())
     122        paths.remove(oldWMPPluginPath);
    140123}
    141124
Note: See TracChangeset for help on using the changeset viewer.