2 // System.Diagnostics.TraceImpl.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2002, 2005 Jonathan Pryor
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Diagnostics;
35 using System.Configuration;
36 using System.Threading;
38 namespace System.Diagnostics {
41 internal class TraceImplSettings {
42 public const string Key = ".__TraceInfoSettingsKey__.";
44 public bool AutoFlush;
45 //public int IndentLevel;
46 public int IndentSize = 4;
47 public TraceListenerCollection Listeners = new TraceListenerCollection (false);
49 public TraceImplSettings ()
51 Listeners.Add (new DefaultTraceListener (), this);
56 internal class TraceImpl {
59 private static object initLock = new object ();
62 private static bool autoFlush;
65 static readonly LocalDataStoreSlot _indentLevelStore = System.Threading.Thread.AllocateDataSlot ();
66 static readonly LocalDataStoreSlot _indentSizeStore = System.Threading.Thread.AllocateDataSlot ();
68 private static int indentLevel {
70 object o = System.Threading.Thread.GetData (_indentLevelStore);
75 set { System.Threading.Thread.SetData (_indentLevelStore, value); }
78 private static int indentSize {
80 object o = System.Threading.Thread.GetData (_indentSizeStore);
85 set { System.Threading.Thread.SetData (_indentSizeStore, value); }
89 private static int indentLevel = 0;
92 private static int indentSize;
102 listeners = new TraceListenerCollection (true);
106 public static bool AutoFlush {
117 public static int IndentLevel {
123 lock (ListenersSyncRoot) {
126 foreach (TraceListener t in Listeners) {
127 t.IndentLevel = indentLevel;
133 public static int IndentSize {
139 lock (ListenersSyncRoot) {
142 foreach (TraceListener t in Listeners) {
143 t.IndentSize = indentSize;
149 private static TraceListenerCollection listeners;
151 public static TraceListenerCollection Listeners {
159 private static object ListenersSyncRoot {
161 return ((ICollection) Listeners).SyncRoot;
165 static bool use_global_lock;
167 static CorrelationManager correlation_manager = new CorrelationManager ();
169 public static CorrelationManager CorrelationManager {
172 return correlation_manager;
177 [MonoLimitation ("the property exists but it does nothing.")]
178 public static bool UseGlobalLock {
181 return use_global_lock;
185 use_global_lock = value;
189 // Initialize the world.
191 // This logically belongs in the static constructor (as it only needs
192 // to be done once), except for one thing: if the .config file has a
193 // syntax error, .NET throws a ConfigurationException. If we read the
194 // .config file in the static ctor, we throw a ConfigurationException
195 // from the static ctor, which results in a TypeLoadException. Oops.
196 // Reading the .config file here will allow the static ctor to
197 // complete successfully, allowing us to throw a normal
198 // ConfigurationException should the .config file contain an error.
200 // There are also some ordering issues.
202 // DiagnosticsConfigurationHandler doesn't store values within TraceImpl,
203 // but instead stores values it reads from the .config file within a
204 // TraceImplSettings object (accessible via the TraceImplSettings.Key key
205 // in the IDictionary returned).
206 private static void InitOnce ()
209 if (initLock != null) {
211 if (listeners == null) {
212 IDictionary d = DiagnosticsConfiguration.Settings;
213 TraceImplSettings s = (TraceImplSettings) d [TraceImplSettings.Key];
215 d.Remove (TraceImplSettings.Key);
217 autoFlush = s.AutoFlush;
218 // indentLevel = s.IndentLevel;
219 indentSize = s.IndentSize;
220 listeners = s.Listeners;
228 // FIXME: According to MSDN, this method should display a dialog box
230 public static void Assert (bool condition)
233 Fail (new StackTrace(true).ToString());
236 // FIXME: According to MSDN, this method should display a dialog box
238 public static void Assert (bool condition, string message)
244 // FIXME: According to MSDN, this method should display a dialog box
246 public static void Assert (bool condition, string message,
247 string detailMessage)
250 Fail (message, detailMessage);
253 public static void Close ()
255 lock (ListenersSyncRoot) {
256 foreach (TraceListener listener in Listeners) {
262 // FIXME: From testing .NET, this method should display a dialog
263 //(it probably depends on the listener)p
265 public static void Fail (string message)
267 lock (ListenersSyncRoot) {
268 foreach (TraceListener listener in Listeners) {
269 listener.Fail (message);
274 // FIXME: From testing .NET, this method should display a dialog
275 // (it probably depends on the listener)p
277 public static void Fail (string message, string detailMessage)
279 lock (ListenersSyncRoot) {
280 foreach (TraceListener listener in Listeners) {
281 listener.Fail (message, detailMessage);
286 public static void Flush ()
288 lock (ListenersSyncRoot) {
289 foreach (TraceListener listener in Listeners){
295 public static void Indent ()
300 public static void Unindent ()
305 public static void Write (object value)
307 lock (ListenersSyncRoot) {
308 foreach (TraceListener listener in Listeners) {
309 listener.Write (value);
317 public static void Write (string message)
319 lock (ListenersSyncRoot) {
320 foreach (TraceListener listener in Listeners) {
321 listener.Write (message);
329 public static void Write (object value, string category)
331 lock (ListenersSyncRoot) {
332 foreach (TraceListener listener in Listeners) {
333 listener.Write (value, category);
341 public static void Write (string message, string category)
343 lock (ListenersSyncRoot) {
344 foreach (TraceListener listener in Listeners) {
345 listener.Write (message, category);
353 public static void WriteIf (bool condition, object value)
359 public static void WriteIf (bool condition, string message)
365 public static void WriteIf (bool condition, object value,
369 Write (value, category);
372 public static void WriteIf (bool condition, string message,
376 Write (message, category);
379 public static void WriteLine (object value)
381 lock (ListenersSyncRoot) {
382 foreach (TraceListener listener in Listeners) {
383 listener.WriteLine (value);
391 public static void WriteLine (string message)
393 lock (ListenersSyncRoot) {
394 foreach (TraceListener listener in Listeners) {
395 listener.WriteLine (message);
403 public static void WriteLine (object value, string category)
405 lock (ListenersSyncRoot) {
406 foreach (TraceListener listener in Listeners) {
407 listener.WriteLine (value, category);
415 public static void WriteLine (string message, string category)
417 lock (ListenersSyncRoot) {
418 foreach (TraceListener listener in Listeners) {
419 listener.WriteLine (message, category);
427 public static void WriteLineIf (bool condition, object value)
433 public static void WriteLineIf (bool condition, string message)
439 public static void WriteLineIf (bool condition, object value,
443 WriteLine (value, category);
446 public static void WriteLineIf (bool condition, string message,
450 WriteLine (message, category);