
Author: ceki Date: Fri Dec 5 19:19:02 2008 New Revision: 2074 Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java Log: - in ContextJNDISelector renamed contextMap as synchronizedContextMap - cosmetic changes in Context Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java Fri Dec 5 19:19:02 2008 @@ -46,13 +46,13 @@ */ public class ContextJNDISelector implements ContextSelector { - private final Map<String, LoggerContext> contextMap; + private final Map<String, LoggerContext> synchronizedContextMap; private final LoggerContext defaultContext; private static final ThreadLocal<LoggerContext> threadLocal = new ThreadLocal<LoggerContext>(); public ContextJNDISelector(LoggerContext context) { - contextMap = Collections + synchronizedContextMap = Collections .synchronizedMap(new HashMap<String, LoggerContext>()); defaultContext = context; } @@ -62,7 +62,7 @@ } public LoggerContext detachLoggerContext(String loggerContextName) { - return contextMap.remove(loggerContextName); + return synchronizedContextMap.remove(loggerContextName); } public LoggerContext getLoggerContext() { @@ -89,13 +89,13 @@ return defaultContext; } else { // Let's see if we already know such a context - LoggerContext loggerContext = contextMap.get(contextName); + LoggerContext loggerContext = synchronizedContextMap.get(contextName); if (loggerContext == null) { // We have to create a new LoggerContext loggerContext = new LoggerContext(); loggerContext.setName(contextName); - contextMap.put(contextName, loggerContext); + synchronizedContextMap.put(contextName, loggerContext); URL url = findConfigFileURL(ctx, loggerContext); if (url != null) { configureLoggerContextByURL(loggerContext, url); @@ -162,12 +162,12 @@ public List<String> getContextNames() { List<String> list = new ArrayList<String>(); - list.addAll(contextMap.keySet()); + list.addAll(synchronizedContextMap.keySet()); return list; } public LoggerContext getLoggerContext(String name) { - return contextMap.get(name); + return synchronizedContextMap.get(name); } /** @@ -176,7 +176,7 @@ * @return the number of managed contexts */ public int getCount() { - return contextMap.size(); + return synchronizedContextMap.size(); } /** Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerContextDeadlockTest.java Fri Dec 5 19:19:02 2008 @@ -0,0 +1,68 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 2000-2008, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ +package ch.qos.logback.classic; + +import java.io.ByteArrayInputStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; + +public class LoggerContextDeadlockTest { + + LoggerContext loggerContext = new LoggerContext(); + JoranConfigurator jc = new JoranConfigurator(); + GetLoggerThread getLoggerThread = new GetLoggerThread(loggerContext); + + @Before + public void setUp() throws Exception { + jc.setContext(loggerContext); + } + + @After + public void tearDown() throws Exception { + } + + @Test(timeout=20000) + public void testLBCLASSIC_81() throws JoranException { + + + getLoggerThread.start(); + for (int i = 0; i < 500; i++) { + ByteArrayInputStream baos = new ByteArrayInputStream(new String( + "<configuration><root level=\"DEBUG\"/></configuration>").getBytes()); + jc.doConfigure(baos); + } + } + + class GetLoggerThread extends Thread { + + final LoggerContext loggerContext; + GetLoggerThread(LoggerContext loggerContext) { + this.loggerContext = loggerContext; + } + @Override + public void run() { + for (int i = 0; i < 10000; i++) { + if(i % 100 == 0) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + } + } + loggerContext.getLogger("a" + i); + } + } + } + +} Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java ============================================================================== --- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java (original) +++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/Context.java Fri Dec 5 19:19:02 2008 @@ -1,11 +1,11 @@ /** - * LOGBack: the reliable, fast and flexible logging library for Java. - * - * Copyright (C) 1999-2006, QOS.ch - * - * This library is free software, you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation. + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 2000-2008, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. */ package ch.qos.logback.core;