Ticket #19638: 19638.synchronized_collection.patch

File 19638.synchronized_collection.patch, 10.1 KB (added by taylor.smock, 6 years ago)

Make pluginList a synchronized collection

  • src/org/openstreetmap/josm/plugins/PluginHandler.java

     
    277277    /**
    278278     * All installed and loaded plugins (resp. their main classes)
    279279     */
    280     static final Collection<PluginProxy> pluginList = new LinkedList<>();
     280    static final Collection<PluginProxy> pluginList = Collections.synchronizedCollection(new LinkedList<>());
    281281
    282282    /**
    283283     * All installed but not loaded plugins
     
    322322     * @since 10982
    323323     */
    324324    public static List<PluginInformation> getPlugins() {
    325         return pluginList.stream().map(PluginProxy::getPluginInformation)
    326                 .sorted(Comparator.comparing(PluginInformation::getName)).collect(Collectors.toList());
     325        synchronized (pluginList) {
     326            return pluginList.stream().map(PluginProxy::getPluginInformation)
     327                    .sorted(Comparator.comparing(PluginInformation::getName)).collect(Collectors.toList());
     328        }
    327329    }
    328330
    329331    /**
     
    598600        MainApplication.worker.submit(() -> {
    599601            // Build list of plugins to download
    600602            Set<PluginInformation> toDownload = new HashSet<>(pluginInfoDownloadTask.getAvailablePlugins());
    601             toDownload.removeIf(info -> !missingRequiredPlugin.contains(info.getName()));
     603            toDownload.removeIf(info -> !missingRequiredPlugin.contains(info.getName())
     604                    && !missingRequiredPlugin.contains(info.provides) || !info.isForCurrentPlatform());
     605            // Remove duplicates
     606            Set<String> possibleDuplicates = toDownload.parallelStream()
     607                    .collect(Collectors.groupingBy(i -> i.provides == null ? i.getName() : i.provides, Collectors.counting()))
     608                    .entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey).collect(Collectors.toSet());
     609            toDownload.removeIf(i -> possibleDuplicates.contains(i.getName()) || possibleDuplicates.contains(i.provides));
    602610            // Check if something has still to be downloaded
    603611            if (!toDownload.isEmpty()) {
    604612                // download plugins
     
    692700
    693701        // Add all plugins already loaded (to include early plugins when checking late ones)
    694702        Collection<PluginInformation> allPlugins = new HashSet<>(plugins);
    695         for (PluginProxy proxy : pluginList) {
    696             allPlugins.add(proxy.getPluginInformation());
     703        synchronized (pluginList) {
     704            for (PluginProxy proxy : pluginList) {
     705                allPlugins.add(proxy.getPluginInformation());
     706            }
    697707        }
    698708
    699709        // Include plugins that have been processed but not been loaded (for javafx plugin)
     
    872882                            continue DEPENDENCIES;
    873883                        }
    874884                    }
    875                     for (PluginProxy proxy : pluginList) {
    876                         if (isDependency(proxy.getPluginInformation(), depName)) {
    877                             cl.addDependency(proxy.getClassLoader());
    878                             continue DEPENDENCIES;
     885                    synchronized (pluginList) {
     886                        for (PluginProxy proxy : pluginList) {
     887                            if (isDependency(proxy.getPluginInformation(), depName)) {
     888                                cl.addDependency(proxy.getClassLoader());
     889                                continue DEPENDENCIES;
     890                            }
    879891                        }
    880892                    }
    881893                    Logging.error("unable to find dependency " + depName + " for plugin " + info.getName());
     
    12321244     * @return The plugin of the specified name, if installed and loaded, or {@code null} otherwise.
    12331245     */
    12341246    public static Object getPlugin(String name) {
    1235         for (PluginProxy plugin : pluginList) {
    1236             if (plugin.getPluginInformation().name.equals(name))
    1237                 return plugin.getPlugin();
     1247        synchronized (pluginList) {
     1248            for (PluginProxy plugin : pluginList) {
     1249                if (plugin.getPluginInformation().name.equals(name))
     1250                    return plugin.getPlugin();
     1251            }
    12381252        }
    12391253        return null;
    12401254    }
     
    12471261     * @since 12323
    12481262     */
    12491263    public static PluginClassLoader getPluginClassLoader(String name) {
    1250         for (PluginProxy plugin : pluginList) {
    1251             if (plugin.getPluginInformation().name.equals(name))
    1252                 return plugin.getClassLoader();
     1264        synchronized (pluginList) {
     1265            for (PluginProxy plugin : pluginList) {
     1266                if (plugin.getPluginInformation().name.equals(name))
     1267                    return plugin.getClassLoader();
     1268            }
    12531269        }
    12541270        return null;
    12551271    }
     
    12601276     * @param downloadSelections list of bounding box selectors
    12611277     */
    12621278    public static void addDownloadSelection(List<DownloadSelection> downloadSelections) {
    1263         for (PluginProxy p : pluginList) {
    1264             p.addDownloadSelection(downloadSelections);
     1279        synchronized (pluginList) {
     1280            for (PluginProxy p : pluginList) {
     1281                p.addDownloadSelection(downloadSelections);
     1282            }
    12651283        }
    12661284    }
    12671285
     
    12711289     */
    12721290    public static Collection<PreferenceSettingFactory> getPreferenceSetting() {
    12731291        Collection<PreferenceSettingFactory> settings = new ArrayList<>();
    1274         for (PluginProxy plugin : pluginList) {
    1275             settings.add(new PluginPreferenceFactory(plugin));
     1292        synchronized (pluginList) {
     1293            for (PluginProxy plugin : pluginList) {
     1294                settings.add(new PluginPreferenceFactory(plugin));
     1295            }
    12761296        }
    12771297        return settings;
    12781298    }
     
    14891509
    14901510        // remember the error position, as multiple plugins may be involved, we search the topmost one
    14911511        int pos = stack.size();
    1492         for (PluginProxy p : pluginList) {
    1493             String baseClass = p.getPluginInformation().className;
    1494             baseClass = baseClass.substring(0, baseClass.lastIndexOf('.'));
    1495             for (int elpos = 0; elpos < pos; ++elpos) {
    1496                 if (stack.get(elpos).getClassName().startsWith(baseClass)) {
    1497                     pos = elpos;
    1498                     err = p;
     1512        synchronized (pluginList) {
     1513            for (PluginProxy p : pluginList) {
     1514                String baseClass = p.getPluginInformation().className;
     1515                baseClass = baseClass.substring(0, baseClass.lastIndexOf('.'));
     1516                for (int elpos = 0; elpos < pos; ++elpos) {
     1517                    if (stack.get(elpos).getClassName().startsWith(baseClass)) {
     1518                        pos = elpos;
     1519                        err = p;
     1520                    }
    14991521                }
    15001522            }
    15011523        }
     
    15571579     */
    15581580    public static Collection<String> getBugReportInformation() {
    15591581        final Collection<String> pl = new TreeSet<>(Config.getPref().getList("plugins", new LinkedList<>()));
    1560         for (final PluginProxy pp : pluginList) {
    1561             PluginInformation pi = pp.getPluginInformation();
    1562             pl.remove(pi.name);
    1563             pl.add(pi.name + " (" + (pi.localversion != null && !pi.localversion.isEmpty()
    1564                     ? pi.localversion : "unknown") + ')');
     1582        synchronized (pluginList) {
     1583            for (final PluginProxy pp : pluginList) {
     1584                PluginInformation pi = pp.getPluginInformation();
     1585                pl.remove(pi.name);
     1586                pl.add(pi.name + " (" + (pi.localversion != null && !pi.localversion.isEmpty()
     1587                        ? pi.localversion : "unknown") + ')');
     1588            }
    15651589        }
    15661590        return pl;
    15671591    }
  • src/org/openstreetmap/josm/plugins/PluginListParser.java

     
    9494        try {
    9595            if (name != null) {
    9696                PluginInformation info = createInfo(name, url, manifest);
    97                 for (PluginProxy plugin : PluginHandler.pluginList) {
    98                     if (plugin.getPluginInformation().name.equals(info.getName())) {
    99                         info.localversion = plugin.getPluginInformation().localversion;
     97                synchronized (PluginHandler.pluginList) {
     98                    for (PluginProxy plugin : PluginHandler.pluginList) {
     99                        if (plugin.getPluginInformation().name.equals(info.getName())) {
     100                            info.localversion = plugin.getPluginInformation().localversion;
     101                        }
    100102                    }
    101103                }
    102104                ret.add(info);
  • src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java

     
    169169    }
    170170
    171171    protected void analyseInProcessPlugins() {
    172         for (PluginProxy proxy : PluginHandler.pluginList) {
    173             PluginInformation info = proxy.getPluginInformation();
    174             if (canceled) return;
    175             if (!availablePlugins.containsKey(info.name)) {
    176                 availablePlugins.put(info.name, info);
    177             } else {
    178                 availablePlugins.get(info.name).localversion = info.localversion;
     172        synchronized (PluginHandler.pluginList) {
     173            for (PluginProxy proxy : PluginHandler.pluginList) {
     174                PluginInformation info = proxy.getPluginInformation();
     175                if (canceled) return;
     176                if (!availablePlugins.containsKey(info.name)) {
     177                    availablePlugins.put(info.name, info);
     178                } else {
     179                    availablePlugins.get(info.name).localversion = info.localversion;
     180                }
    179181            }
    180182        }
    181183    }