Permalink
Browse files

Fixed [ThreadAgnostic] attribute handling across the board.

  • Loading branch information...
1 parent 18c8eb0 commit f405c7e62be5582157fde761606b7edd5fd847fa @jkowalski committed Jul 11, 2011
Showing with 229 additions and 4 deletions.
  1. +1 −0 src/NLog.Extended/NLog.Extended.netfx40.csproj
  2. +1 −1 src/NLog.proj
  3. +1 −0 src/NLog/Conditions/ConditionExpression.cs
  4. +1 −0 src/NLog/LayoutRenderers/MachineNameLayoutRenderer.cs
  5. +1 −0 src/NLog/LayoutRenderers/NLogDirLayoutRenderer.cs
  6. +1 −0 src/NLog/LayoutRenderers/ProcessIdLayoutRenderer.cs
  7. +1 −0 src/NLog/LayoutRenderers/ProcessNameLayoutRenderer.cs
  8. +2 −0 src/NLog/LayoutRenderers/Wrappers/CachedLayoutRendererWrapper.cs
  9. +2 −0 src/NLog/LayoutRenderers/Wrappers/FileSystemNormalizeLayoutRendererWrapper.cs
  10. +2 −0 src/NLog/LayoutRenderers/Wrappers/LowercaseLayoutRendererWrapper.cs
  11. +3 −0 src/NLog/LayoutRenderers/Wrappers/OnExceptionLayoutRendererWrapper.cs
  12. +2 −0 src/NLog/LayoutRenderers/Wrappers/PaddingLayoutRendererWrapper.cs
  13. +2 −0 src/NLog/LayoutRenderers/Wrappers/ReplaceLayoutRendererWrapper.cs
  14. +1 −0 src/NLog/LayoutRenderers/Wrappers/Rot13LayoutRendererWrapper.cs
  15. +2 −0 src/NLog/LayoutRenderers/Wrappers/TrimWhiteSpaceLayoutRendererWrapper.cs
  16. +2 −0 src/NLog/LayoutRenderers/Wrappers/UppercaseLayoutRendererWrapper.cs
  17. +2 −0 src/NLog/LayoutRenderers/Wrappers/UrlEncodeLayoutRendererWrapper.cs
  18. +1 −0 src/NLog/LayoutRenderers/Wrappers/WhenEmptyLayoutRendererWrapper.cs
  19. +1 −0 src/NLog/LayoutRenderers/Wrappers/WhenLayoutRendererWrapper.cs
  20. +2 −0 src/NLog/LayoutRenderers/Wrappers/XmlEncodeLayoutRendererWrapper.cs
  21. +32 −1 src/NLog/Layouts/Layout.cs
  22. +1 −0 src/NLog/NLog.netfx40.csproj
  23. +153 −0 tests/NLog.UnitTests/Layouts/ThreadAgnosticTests.cs
  24. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.monodevelop.csproj
  25. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj
  26. +2 −2 tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj
  27. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj
  28. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj
  29. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj
  30. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj
  31. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj
  32. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj
  33. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.wp7.csproj
  34. +1 −0 tests/NLog.UnitTests/NLog.UnitTests.wp71.csproj
@@ -15,6 +15,7 @@
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\NLog.snk</AssemblyOriginatorKeyFile>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
View
@@ -74,7 +74,7 @@
<MSTest9>$(VS90COMNTOOLS)..\IDE\MSTest.exe</MSTest9>
<MSTest10>$(VS100COMNTOOLS)..\IDE\MSTest.exe</MSTest10>
- <StyleCopTargetsFile>$(MSBuildExtensionsPath)\Microsoft\StyleCop\v4.4\Microsoft.StyleCop.Targets</StyleCopTargetsFile>
+ <StyleCopTargetsFile>$(MSBuildExtensionsPath)\Microsoft\StyleCop\v4.5\Microsoft.StyleCop.Targets</StyleCopTargetsFile>
<StyleCopProperties Condition="'$(DisableStyleCop)' == 'false' and Exists('$(StyleCopTargetsFile)')">StyleCopTargetsFile=$(StyleCopTargetsFile)</StyleCopProperties>
</PropertyGroup>
@@ -41,6 +41,7 @@ namespace NLog.Conditions
/// Base class for representing nodes in condition expression trees.
/// </summary>
[NLogConfigurationItem]
+ [ThreadAgnostic]
public abstract class ConditionExpression
{
/// <summary>
@@ -46,6 +46,7 @@ namespace NLog.LayoutRenderers
/// </summary>
[LayoutRenderer("machinename")]
[AppDomainFixedOutput]
+ [ThreadAgnostic]
public class MachineNameLayoutRenderer : LayoutRenderer
{
internal string MachineName { get; private set; }
@@ -45,6 +45,7 @@ namespace NLog.LayoutRenderers
/// </summary>
[LayoutRenderer("nlogdir")]
[AppDomainFixedOutput]
+ [ThreadAgnostic]
public class NLogDirLayoutRenderer : LayoutRenderer
{
/// <summary>
@@ -45,6 +45,7 @@ namespace NLog.LayoutRenderers
/// </summary>
[LayoutRenderer("processid")]
[AppDomainFixedOutput]
+ [ThreadAgnostic]
public class ProcessIdLayoutRenderer : LayoutRenderer
{
/// <summary>
@@ -45,6 +45,7 @@ namespace NLog.LayoutRenderers
/// </summary>
[LayoutRenderer("processname")]
[AppDomainFixedOutput]
+ [ThreadAgnostic]
public class ProcessNameLayoutRenderer : LayoutRenderer
{
/// <summary>
@@ -34,6 +34,7 @@
namespace NLog.LayoutRenderers.Wrappers
{
using System.ComponentModel;
+ using NLog.Config;
/// <summary>
/// Applies caching to another layout output.
@@ -43,6 +44,7 @@ namespace NLog.LayoutRenderers.Wrappers
/// </remarks>
[LayoutRenderer("cached")]
[AmbientProperty("Cached")]
+ [ThreadAgnostic]
public sealed class CachedLayoutRendererWrapper : WrapperLayoutRendererBase
{
private string cachedValue;
@@ -35,12 +35,14 @@ namespace NLog.LayoutRenderers.Wrappers
{
using System.ComponentModel;
using System.Text;
+ using NLog.Config;
/// <summary>
/// Filters characters not allowed in the file names by replacing them with safe character.
/// </summary>
[LayoutRenderer("filesystem-normalize")]
[AmbientProperty("FSNormalize")]
+ [ThreadAgnostic]
public sealed class FileSystemNormalizeLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -35,12 +35,14 @@ namespace NLog.LayoutRenderers.Wrappers
{
using System.ComponentModel;
using System.Globalization;
+ using NLog.Config;
/// <summary>
/// Converts the result of another layout output to lower case.
/// </summary>
[LayoutRenderer("lowercase")]
[AmbientProperty("Lowercase")]
+ [ThreadAgnostic]
public sealed class LowercaseLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -33,10 +33,13 @@
namespace NLog.LayoutRenderers.Wrappers
{
+ using NLog.Config;
+
/// <summary>
/// Only outputs the inner layout when exception has been defined for log message.
/// </summary>
[LayoutRenderer("onexception")]
+ [ThreadAgnostic]
public sealed class OnExceptionLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -35,6 +35,7 @@ namespace NLog.LayoutRenderers.Wrappers
{
using System;
using System.ComponentModel;
+ using NLog.Config;
/// <summary>
/// Applies padding to another layout output.
@@ -43,6 +44,7 @@ namespace NLog.LayoutRenderers.Wrappers
[AmbientProperty("Padding")]
[AmbientProperty("PadCharacter")]
[AmbientProperty("FixedLength")]
+ [ThreadAgnostic]
public sealed class PaddingLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -34,11 +34,13 @@
namespace NLog.LayoutRenderers.Wrappers
{
using System.Text.RegularExpressions;
+ using NLog.Config;
/// <summary>
/// Replaces a string in the output of another layout with another string.
/// </summary>
[LayoutRenderer("replace")]
+ [ThreadAgnostic]
public sealed class ReplaceLayoutRendererWrapper : WrapperLayoutRendererBase
{
private Regex regex;
@@ -44,6 +44,7 @@ namespace NLog.LayoutRenderers.Wrappers
/// </remarks>
[LayoutRenderer("rot13")]
[AppDomainFixedOutput]
+ [ThreadAgnostic]
public sealed class Rot13LayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -35,12 +35,14 @@ namespace NLog.LayoutRenderers.Wrappers
{
using System.ComponentModel;
using System.Globalization;
+ using NLog.Config;
/// <summary>
/// Trims the whitespace from the result of another layout renderer.
/// </summary>
[LayoutRenderer("trim-whitespace")]
[AmbientProperty("TrimWhiteSpace")]
+ [ThreadAgnostic]
public sealed class TrimWhiteSpaceLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -35,12 +35,14 @@ namespace NLog.LayoutRenderers.Wrappers
{
using System.ComponentModel;
using System.Globalization;
+ using NLog.Config;
/// <summary>
/// Converts the result of another layout output to upper case.
/// </summary>
[LayoutRenderer("uppercase")]
[AmbientProperty("Uppercase")]
+ [ThreadAgnostic]
public sealed class UppercaseLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -33,12 +33,14 @@
namespace NLog.LayoutRenderers.Wrappers
{
+ using NLog.Config;
using NLog.Internal;
/// <summary>
/// Encodes the result of another layout output for use with URLs.
/// </summary>
[LayoutRenderer("url-encode")]
+ [ThreadAgnostic]
public sealed class UrlEncodeLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -41,6 +41,7 @@ namespace NLog.LayoutRenderers.Wrappers
/// </summary>
[LayoutRenderer("whenEmpty")]
[AmbientProperty("WhenEmpty")]
+ [ThreadAgnostic]
public sealed class WhenEmptyLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -41,6 +41,7 @@ namespace NLog.LayoutRenderers.Wrappers
/// </summary>
[LayoutRenderer("when")]
[AmbientProperty("When")]
+ [ThreadAgnostic]
public sealed class WhenLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -38,12 +38,14 @@ namespace NLog.LayoutRenderers.Wrappers
using System.Globalization;
using System.Text;
using System.Xml;
+ using NLog.Config;
/// <summary>
/// Converts the result of another layout output to be XML-compliant.
/// </summary>
[LayoutRenderer("xml-encode")]
[AmbientProperty("XmlEncode")]
+ [ThreadAgnostic]
public sealed class XmlEncodeLayoutRendererWrapper : WrapperLayoutRendererBase
{
/// <summary>
@@ -45,6 +45,20 @@ namespace NLog.Layouts
public abstract class Layout : ISupportsInitialize, IRenderable
{
private bool isInitialized;
+ private bool threadAgnostic;
+
+ /// <summary>
+ /// Gets a value indicating whether this layout is thread-agnostic (can be rendered on any thread).
+ /// </summary>
+ /// <remarks>
+ /// Layout is thread-agnostic if it has been marked with [ThreadAgnostic] attribute and all its children are
+ /// like that as well.
+ /// Thread-agnostic layouts only use contents of <see cref="LogEventInfo"/> for its output.
+ /// </remarks>
+ internal bool IsThreadAgnostic
+ {
+ get { return this.threadAgnostic; }
+ }
/// <summary>
/// Gets the logging configuration this target is part of.
@@ -94,7 +108,10 @@ public static Layout FromString(string layoutText, ConfigurationItemFactory conf
/// </remarks>
public virtual void Precalculate(LogEventInfo logEvent)
{
- this.Render(logEvent);
+ if (!this.threadAgnostic)
+ {
+ this.Render(logEvent);
+ }
}
/// <summary>
@@ -140,6 +157,20 @@ internal void Initialize(LoggingConfiguration configuration)
{
this.LoggingConfiguration = configuration;
this.isInitialized = true;
+
+ // determine whether the layout is thread-agnostic
+ // layout is thread agnostic if it is thread-agnostic and
+ // all its nested objects are thread-agnostic.
+ this.threadAgnostic = true;
+ foreach (object item in ObjectGraphScanner.FindReachableObjects<object>(this))
+ {
+ if (!item.GetType().IsDefined(typeof(ThreadAgnosticAttribute), true))
+ {
+ this.threadAgnostic = false;
+ break;
+ }
+ }
+
this.InitializeLayout();
}
}
@@ -18,6 +18,7 @@
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<StyleCopTargetsFile>$(MSBuildExtensionsPath)\Microsoft\StyleCop\v4.4\Microsoft.StyleCop.Targets</StyleCopTargetsFile>
<RunCodeAnalysis Condition=" '$(BuildingInsideVisualStudio)' != 'true' ">true</RunCodeAnalysis>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
Oops, something went wrong.

0 comments on commit f405c7e

Please sign in to comment.