Bug 573396 - Make InternalPlatform.getLog() thread-safe The method InternalPlatform.getLog(Bundle) was not guarded against concurrent access. If multiple threads concurrently query a log the 'logs'-map could have ended in an inconsistent state. However the ExtendedLogServiceFactory of the ExtendedLogService used to create a new logger seems to be thread-safe. Change-Id: Id12833936c32fce28f877292d5363152a4fccdbb Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.runtime/+/180289 Tested-by: Platform Bot <platform-bot@eclipse.org> Reviewed-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java index 561f15d..9c0b1cb 100644 --- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java +++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
@@ -19,6 +19,7 @@ import java.io.File; import java.net.URL; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.core.internal.preferences.exchange.ILegacyPreferences; import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService; import org.eclipse.core.internal.preferences.legacy.InitLegacyPreferences; @@ -60,8 +61,7 @@ private static final String KEYRING = "-keyring"; //$NON-NLS-1$ private String keyringFile; - //XXX This is not synchronized - private Map<Bundle,Log> logs = new HashMap<>(5); + private Map<Bundle, Log> logs = new ConcurrentHashMap<>(5); private static final String[] OS_LIST = { Platform.OS_LINUX, Platform.OS_MACOSX, Platform.OS_WIN32 }; private String password = ""; //$NON-NLS-1$ @@ -355,16 +355,14 @@ * The system log listener needs to be optional: turned on or off. What about a system property? :-) */ public ILog getLog(Bundle bundle) { - Log result = logs.get(bundle); - if (result != null) - return result; - ExtendedLogService logService = extendedLogTracker.getService(); - Logger logger = logService != null ? logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME) : null; - result = new Log(bundle, logger); - ExtendedLogReaderService logReader = logReaderTracker.getService(); - logReader.addLogListener(result, result); - logs.put(bundle, result); - return result; + return logs.computeIfAbsent(bundle, b -> { + ExtendedLogService logService = extendedLogTracker.getService(); + Logger logger = logService != null ? logService.getLogger(b, PlatformLogWriter.EQUINOX_LOGGER_NAME) : null; + Log log = new Log(b, logger); + ExtendedLogReaderService logReader = logReaderTracker.getService(); + logReader.addLogListener(log, log); + return log; + }); } public String getNL() {