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;
166 static CorrelationManager correlation_manager = new CorrelationManager ();
168 public static CorrelationManager CorrelationManager {
171 return correlation_manager;
175 [MonoLimitation ("the property exists but it does nothing.")]
176 public static bool UseGlobalLock {
179 return use_global_lock;
183 use_global_lock = value;
187 // Initialize the world.
189 // This logically belongs in the static constructor (as it only needs
190 // to be done once), except for one thing: if the .config file has a
191 // syntax error, .NET throws a ConfigurationException. If we read the
192 // .config file in the static ctor, we throw a ConfigurationException
193 // from the static ctor, which results in a TypeLoadException. Oops.
194 // Reading the .config file here will allow the static ctor to
195 // complete successfully, allowing us to throw a normal
196 // ConfigurationException should the .config file contain an error.
198 // There are also some ordering issues.
200 // DiagnosticsConfigurationHandler doesn't store values within TraceImpl,
201 // but instead stores values it reads from the .config file within a
202 // TraceImplSettings object (accessible via the TraceImplSettings.Key key
203 // in the IDictionary returned).
204 private static void InitOnce ()
207 if (initLock != null) {
209 if (listeners == null) {
210 IDictionary d = DiagnosticsConfiguration.Settings;
211 TraceImplSettings s = (TraceImplSettings) d [TraceImplSettings.Key];
213 d.Remove (TraceImplSettings.Key);
215 autoFlush = s.AutoFlush;
216 // indentLevel = s.IndentLevel;
217 indentSize = s.IndentSize;
218 listeners = s.Listeners;
226 // FIXME: According to MSDN, this method should display a dialog box
228 public static void Assert (bool condition)
231 Fail (new StackTrace(true).ToString());
234 // FIXME: According to MSDN, this method should display a dialog box
236 public static void Assert (bool condition, string message)
242 // FIXME: According to MSDN, this method should display a dialog box
244 public static void Assert (bool condition, string message,
245 string detailMessage)
248 Fail (message, detailMessage);
251 public static void Close ()
253 lock (ListenersSyncRoot) {
254 foreach (TraceListener listener in Listeners) {
260 // FIXME: From testing .NET, this method should display a dialog
261 //(it probably depends on the listener)p
263 public static void Fail (string message)
265 lock (ListenersSyncRoot) {
266 foreach (TraceListener listener in Listeners) {
267 listener.Fail (message);
272 // FIXME: From testing .NET, this method should display a dialog
273 // (it probably depends on the listener)p
275 public static void Fail (string message, string detailMessage)
277 lock (ListenersSyncRoot) {
278 foreach (TraceListener listener in Listeners) {
279 listener.Fail (message, detailMessage);
284 public static void Flush ()
286 lock (ListenersSyncRoot) {
287 foreach (TraceListener listener in Listeners){
293 public static void Indent ()
298 public static void Unindent ()
303 public static void Write (object value)
305 lock (ListenersSyncRoot) {
306 foreach (TraceListener listener in Listeners) {
307 listener.Write (value);
315 public static void Write (string message)
317 lock (ListenersSyncRoot) {
318 foreach (TraceListener listener in Listeners) {
319 listener.Write (message);
327 public static void Write (object value, string category)
329 lock (ListenersSyncRoot) {
330 foreach (TraceListener listener in Listeners) {
331 listener.Write (value, category);
339 public static void Write (string message, string category)
341 lock (ListenersSyncRoot) {
342 foreach (TraceListener listener in Listeners) {
343 listener.Write (message, category);
351 public static void WriteIf (bool condition, object value)
357 public static void WriteIf (bool condition, string message)
363 public static void WriteIf (bool condition, object value,
367 Write (value, category);
370 public static void WriteIf (bool condition, string message,
374 Write (message, category);
377 public static void WriteLine (object value)
379 lock (ListenersSyncRoot) {
380 foreach (TraceListener listener in Listeners) {
381 listener.WriteLine (value);
389 public static void WriteLine (string message)
391 lock (ListenersSyncRoot) {
392 foreach (TraceListener listener in Listeners) {
393 listener.WriteLine (message);
401 public static void WriteLine (object value, string category)
403 lock (ListenersSyncRoot) {
404 foreach (TraceListener listener in Listeners) {
405 listener.WriteLine (value, category);
413 public static void WriteLine (string message, string category)
415 lock (ListenersSyncRoot) {
416 foreach (TraceListener listener in Listeners) {
417 listener.WriteLine (message, category);
425 public static void WriteLineIf (bool condition, object value)
431 public static void WriteLineIf (bool condition, string message)
437 public static void WriteLineIf (bool condition, object value,
441 WriteLine (value, category);
444 public static void WriteLineIf (bool condition, string message,
448 WriteLine (message, category);