minor fix for bug 9520:
[mono.git] / mcs / class / System / System.Diagnostics / TraceImpl.cs
1 //
2 // System.Diagnostics.TraceImpl.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2002, 2005 Jonathan Pryor
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31
32 using System;
33 using System.Collections;
34 using System.Diagnostics;
35 using System.Configuration;
36 using System.Threading;
37
38 namespace System.Diagnostics {
39
40 #if !MOBILE
41         internal class TraceImplSettings {
42                 public const string Key = ".__TraceInfoSettingsKey__.";
43
44                 public bool AutoFlush;
45                 //public int IndentLevel;
46                 public int IndentSize = 4;
47                 public TraceListenerCollection Listeners = new TraceListenerCollection (false);
48
49                 public TraceImplSettings ()
50                 {
51                         Listeners.Add (new DefaultTraceListener (), this);
52                 }
53         }
54 #endif
55
56         internal class TraceImpl {
57
58 #if !MOBILE
59                 private static object initLock = new object ();
60 #endif
61
62                 private static bool autoFlush;
63
64 #if TARGET_JVM
65                 static readonly LocalDataStoreSlot _indentLevelStore = System.Threading.Thread.AllocateDataSlot ();
66                 static readonly LocalDataStoreSlot _indentSizeStore = System.Threading.Thread.AllocateDataSlot ();
67
68                 private static int indentLevel {
69                         get {
70                                 object o = System.Threading.Thread.GetData (_indentLevelStore);
71                                 if (o == null)
72                                         return 0;
73                                 return (int) o;
74                         }
75                         set { System.Threading.Thread.SetData (_indentLevelStore, value); }
76                 }
77
78                 private static int indentSize {
79                         get {
80                                 object o = System.Threading.Thread.GetData (_indentSizeStore);
81                                 if (o == null)
82                                         return 0;
83                                 return (int) o;
84                         }
85                         set { System.Threading.Thread.SetData (_indentSizeStore, value); }
86                 }
87 #else
88                 [ThreadStatic]
89                 private static int indentLevel = 0;
90
91                 [ThreadStatic]
92                 private static int indentSize;
93 #endif
94
95                 private TraceImpl ()
96                 {
97                 }
98
99 #if MOBILE
100                 static TraceImpl ()
101                 {
102                         listeners = new TraceListenerCollection (true);
103                 }
104 #endif
105
106                 public static bool AutoFlush {
107                         get {
108                                 InitOnce ();
109                                 return autoFlush;
110                         }
111                         set {
112                                 InitOnce ();
113                                 autoFlush = value;
114                         }
115                 }
116
117                 public static int IndentLevel {
118                         get {
119                                 InitOnce ();
120                                 return indentLevel;
121                         }
122                         set {
123                                 lock (ListenersSyncRoot) {
124                                         indentLevel = value;
125
126                                         foreach (TraceListener t in Listeners) {
127                                                 t.IndentLevel = indentLevel;
128                                         }
129                                 }
130                         }
131                 }
132
133                 public static int IndentSize {
134                         get {
135                                 InitOnce ();
136                                 return indentSize;
137                         }
138                         set {
139                                 lock (ListenersSyncRoot) {
140                                         indentSize = value;
141
142                                         foreach (TraceListener t in Listeners) {
143                                                 t.IndentSize = indentSize;
144                                         }
145                                 }
146                         }
147                 }
148
149                 private static TraceListenerCollection listeners;
150
151                 public static TraceListenerCollection Listeners {
152                         get {
153                                 InitOnce ();
154
155                                 return listeners;
156                         }
157                 }
158
159                 private static object ListenersSyncRoot {
160                         get {
161                                 return ((ICollection) Listeners).SyncRoot;
162                         }
163                 }
164
165                 static bool use_global_lock;
166 #if !MOBILE
167                 static CorrelationManager correlation_manager = new CorrelationManager ();
168
169                 public static CorrelationManager CorrelationManager {
170                         get {
171                                 InitOnce ();
172                                 return correlation_manager;
173                         }
174                 }
175 #endif
176
177                 [MonoLimitation ("the property exists but it does nothing.")]
178                 public static bool UseGlobalLock {
179                         get {
180                                 InitOnce ();
181                                 return use_global_lock;
182                         }
183                         set {
184                                 InitOnce ();
185                                 use_global_lock = value;
186                         }
187                 }
188
189                 // Initialize the world.
190                 //
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.
199                 //
200                 // There are also some ordering issues.
201                 //
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 ()
207                 {
208 #if !MOBILE
209                         if (initLock != null) {
210                                 lock (initLock) {
211                                         if (listeners == null) {
212                                                 IDictionary       d = DiagnosticsConfiguration.Settings;
213                                                 TraceImplSettings s = (TraceImplSettings) d [TraceImplSettings.Key];
214
215                                                 d.Remove (TraceImplSettings.Key);
216
217                                                 autoFlush   = s.AutoFlush;
218 //                                              indentLevel = s.IndentLevel;
219                                                 indentSize  = s.IndentSize;
220                                                 listeners   = s.Listeners;
221                                         }
222                                 }
223                                 initLock = null;
224                         }
225 #endif
226                 }
227
228                 // FIXME: According to MSDN, this method should display a dialog box
229                 [MonoTODO]
230                 public static void Assert (bool condition)
231                 {
232                         if (!condition)
233                                 Fail (new StackTrace(true).ToString());
234                 }
235
236                 // FIXME: According to MSDN, this method should display a dialog box
237                 [MonoTODO]
238                 public static void Assert (bool condition, string message)
239                 {
240                         if (!condition)
241                                 Fail (message);
242                 }
243
244                 // FIXME: According to MSDN, this method should display a dialog box
245                 [MonoTODO]
246                 public static void Assert (bool condition, string message, 
247                         string detailMessage)
248                 {
249                         if (!condition)
250                                 Fail (message, detailMessage);
251                 }
252
253                 public static void Close ()
254                 {
255                         lock (ListenersSyncRoot) {
256                                 foreach (TraceListener listener in Listeners) {
257                                         listener.Close ();
258                                 }
259                         }
260                 }
261
262                 // FIXME: From testing .NET, this method should display a dialog
263                 //(it probably depends on the listener)p
264                 [MonoTODO]
265                 public static void Fail (string message)
266                 {
267                         lock (ListenersSyncRoot) {
268                                 foreach (TraceListener listener in Listeners) {
269                                         listener.Fail (message);
270                                 }
271                         }
272                 }
273
274                 // FIXME: From testing .NET, this method should display a dialog
275                 // (it probably depends on the listener)p
276                 [MonoTODO]
277                 public static void Fail (string message, string detailMessage)
278                 {
279                         lock (ListenersSyncRoot) {
280                                 foreach (TraceListener listener in Listeners) {
281                                         listener.Fail (message, detailMessage);
282                                 }
283                         }
284                 }
285
286                 public static void Flush ()
287                 {
288                         lock (ListenersSyncRoot) {
289                                 foreach (TraceListener listener in Listeners){
290                                         listener.Flush ();
291                                 }
292                         }
293                 }
294
295                 public static void Indent ()
296                 {
297                         IndentLevel ++;
298                 }
299
300                 public static void Unindent ()
301                 {
302                         IndentLevel --;
303                 }
304
305                 public static void Write (object value)
306                 {
307                         lock (ListenersSyncRoot) {
308                                 foreach (TraceListener listener in Listeners) {
309                                         listener.Write (value);
310
311                                         if (AutoFlush)
312                                                 listener.Flush ();
313                                 }
314                         }
315                 }
316
317                 public static void Write (string message)
318                 {
319                         lock (ListenersSyncRoot) {
320                                 foreach (TraceListener listener in Listeners) {
321                                         listener.Write (message);
322
323                                         if (AutoFlush)
324                                                 listener.Flush ();
325                                 }
326                         }
327                 }
328
329                 public static void Write (object value, string category)
330                 {
331                         lock (ListenersSyncRoot) {
332                                 foreach (TraceListener listener in Listeners) {
333                                         listener.Write (value, category);
334
335                                         if (AutoFlush)
336                                                 listener.Flush ();
337                                 }
338                         }
339                 }
340
341                 public static void Write (string message, string category)
342                 {
343                         lock (ListenersSyncRoot) {
344                                 foreach (TraceListener listener in Listeners) {
345                                         listener.Write (message, category);
346
347                                         if (AutoFlush)
348                                                 listener.Flush ();
349                                 }
350                         }
351                 }
352
353                 public static void WriteIf (bool condition, object value)
354                 {
355                         if (condition)
356                                 Write (value);
357                 }
358
359                 public static void WriteIf (bool condition, string message)
360                 {
361                         if (condition)
362                                 Write (message);
363                 }
364
365                 public static void WriteIf (bool condition, object value, 
366                         string category)
367                 {
368                         if (condition)
369                                 Write (value, category);
370                 }
371
372                 public static void WriteIf (bool condition, string message, 
373                         string category)
374                 {
375                         if (condition)
376                                 Write (message, category);
377                 }
378
379                 public static void WriteLine (object value)
380                 {
381                         lock (ListenersSyncRoot) {
382                                 foreach (TraceListener listener in Listeners) {
383                                         listener.WriteLine (value);
384
385                                         if (AutoFlush)
386                                                 listener.Flush ();
387                                 }
388                         }
389                 }
390
391                 public static void WriteLine (string message)
392                 {
393                         lock (ListenersSyncRoot) {
394                                 foreach (TraceListener listener in Listeners) {
395                                         listener.WriteLine (message);
396
397                                         if (AutoFlush)
398                                                 listener.Flush ();
399                                 }
400                         }
401                 }
402
403                 public static void WriteLine (object value, string category)
404                 {
405                         lock (ListenersSyncRoot) {
406                                 foreach (TraceListener listener in Listeners) {
407                                         listener.WriteLine (value, category);
408
409                                         if (AutoFlush)
410                                                 listener.Flush ();
411                                 }
412                         }
413                 }
414
415                 public static void WriteLine (string message, string category)
416                 {
417                         lock (ListenersSyncRoot) {
418                                 foreach (TraceListener listener in Listeners) {
419                                         listener.WriteLine (message, category);
420
421                                         if (AutoFlush)
422                                                 listener.Flush ();
423                                 }
424                         }
425                 }
426
427                 public static void WriteLineIf (bool condition, object value)
428                 {
429                         if (condition)
430                                 WriteLine (value);
431                 }
432
433                 public static void WriteLineIf (bool condition, string message)
434                 {
435                         if (condition)
436                                 WriteLine (message);
437                 }
438
439                 public static void WriteLineIf (bool condition, object value, 
440                         string category)
441                 {
442                         if (condition)
443                                 WriteLine (value, category);
444                 }
445
446                 public static void WriteLineIf (bool condition, string message, 
447                         string category)
448                 {
449                         if (condition)
450                                 WriteLine (message, category);
451                 }
452         }
453 }
454