Added tests for Task.WhenAll w/ empty list
[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                 static CorrelationManager correlation_manager = new CorrelationManager ();
167
168                 public static CorrelationManager CorrelationManager {
169                         get {
170                                 InitOnce ();
171                                 return correlation_manager;
172                         }
173                 }
174
175                 [MonoLimitation ("the property exists but it does nothing.")]
176                 public static bool UseGlobalLock {
177                         get {
178                                 InitOnce ();
179                                 return use_global_lock;
180                         }
181                         set {
182                                 InitOnce ();
183                                 use_global_lock = value;
184                         }
185                 }
186
187                 // Initialize the world.
188                 //
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.
197                 //
198                 // There are also some ordering issues.
199                 //
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 ()
205                 {
206 #if !MOBILE
207                         if (initLock != null) {
208                                 lock (initLock) {
209                                         if (listeners == null) {
210                                                 IDictionary       d = DiagnosticsConfiguration.Settings;
211                                                 TraceImplSettings s = (TraceImplSettings) d [TraceImplSettings.Key];
212
213                                                 d.Remove (TraceImplSettings.Key);
214
215                                                 autoFlush   = s.AutoFlush;
216 //                                              indentLevel = s.IndentLevel;
217                                                 indentSize  = s.IndentSize;
218                                                 listeners   = s.Listeners;
219                                         }
220                                 }
221                                 initLock = null;
222                         }
223 #endif
224                 }
225
226                 // FIXME: According to MSDN, this method should display a dialog box
227                 [MonoTODO]
228                 public static void Assert (bool condition)
229                 {
230                         if (!condition)
231                                 Fail (new StackTrace(true).ToString());
232                 }
233
234                 // FIXME: According to MSDN, this method should display a dialog box
235                 [MonoTODO]
236                 public static void Assert (bool condition, string message)
237                 {
238                         if (!condition)
239                                 Fail (message);
240                 }
241
242                 // FIXME: According to MSDN, this method should display a dialog box
243                 [MonoTODO]
244                 public static void Assert (bool condition, string message, 
245                         string detailMessage)
246                 {
247                         if (!condition)
248                                 Fail (message, detailMessage);
249                 }
250
251                 public static void Close ()
252                 {
253                         lock (ListenersSyncRoot) {
254                                 foreach (TraceListener listener in Listeners) {
255                                         listener.Close ();
256                                 }
257                         }
258                 }
259
260                 // FIXME: From testing .NET, this method should display a dialog
261                 //(it probably depends on the listener)p
262                 [MonoTODO]
263                 public static void Fail (string message)
264                 {
265                         lock (ListenersSyncRoot) {
266                                 foreach (TraceListener listener in Listeners) {
267                                         listener.Fail (message);
268                                 }
269                         }
270                 }
271
272                 // FIXME: From testing .NET, this method should display a dialog
273                 // (it probably depends on the listener)p
274                 [MonoTODO]
275                 public static void Fail (string message, string detailMessage)
276                 {
277                         lock (ListenersSyncRoot) {
278                                 foreach (TraceListener listener in Listeners) {
279                                         listener.Fail (message, detailMessage);
280                                 }
281                         }
282                 }
283
284                 public static void Flush ()
285                 {
286                         lock (ListenersSyncRoot) {
287                                 foreach (TraceListener listener in Listeners){
288                                         listener.Flush ();
289                                 }
290                         }
291                 }
292
293                 public static void Indent ()
294                 {
295                         IndentLevel ++;
296                 }
297
298                 public static void Unindent ()
299                 {
300                         IndentLevel --;
301                 }
302
303                 public static void Write (object value)
304                 {
305                         lock (ListenersSyncRoot) {
306                                 foreach (TraceListener listener in Listeners) {
307                                         listener.Write (value);
308
309                                         if (AutoFlush)
310                                                 listener.Flush ();
311                                 }
312                         }
313                 }
314
315                 public static void Write (string message)
316                 {
317                         lock (ListenersSyncRoot) {
318                                 foreach (TraceListener listener in Listeners) {
319                                         listener.Write (message);
320
321                                         if (AutoFlush)
322                                                 listener.Flush ();
323                                 }
324                         }
325                 }
326
327                 public static void Write (object value, string category)
328                 {
329                         lock (ListenersSyncRoot) {
330                                 foreach (TraceListener listener in Listeners) {
331                                         listener.Write (value, category);
332
333                                         if (AutoFlush)
334                                                 listener.Flush ();
335                                 }
336                         }
337                 }
338
339                 public static void Write (string message, string category)
340                 {
341                         lock (ListenersSyncRoot) {
342                                 foreach (TraceListener listener in Listeners) {
343                                         listener.Write (message, category);
344
345                                         if (AutoFlush)
346                                                 listener.Flush ();
347                                 }
348                         }
349                 }
350
351                 public static void WriteIf (bool condition, object value)
352                 {
353                         if (condition)
354                                 Write (value);
355                 }
356
357                 public static void WriteIf (bool condition, string message)
358                 {
359                         if (condition)
360                                 Write (message);
361                 }
362
363                 public static void WriteIf (bool condition, object value, 
364                         string category)
365                 {
366                         if (condition)
367                                 Write (value, category);
368                 }
369
370                 public static void WriteIf (bool condition, string message, 
371                         string category)
372                 {
373                         if (condition)
374                                 Write (message, category);
375                 }
376
377                 public static void WriteLine (object value)
378                 {
379                         lock (ListenersSyncRoot) {
380                                 foreach (TraceListener listener in Listeners) {
381                                         listener.WriteLine (value);
382
383                                         if (AutoFlush)
384                                                 listener.Flush ();
385                                 }
386                         }
387                 }
388
389                 public static void WriteLine (string message)
390                 {
391                         lock (ListenersSyncRoot) {
392                                 foreach (TraceListener listener in Listeners) {
393                                         listener.WriteLine (message);
394
395                                         if (AutoFlush)
396                                                 listener.Flush ();
397                                 }
398                         }
399                 }
400
401                 public static void WriteLine (object value, string category)
402                 {
403                         lock (ListenersSyncRoot) {
404                                 foreach (TraceListener listener in Listeners) {
405                                         listener.WriteLine (value, category);
406
407                                         if (AutoFlush)
408                                                 listener.Flush ();
409                                 }
410                         }
411                 }
412
413                 public static void WriteLine (string message, string category)
414                 {
415                         lock (ListenersSyncRoot) {
416                                 foreach (TraceListener listener in Listeners) {
417                                         listener.WriteLine (message, category);
418
419                                         if (AutoFlush)
420                                                 listener.Flush ();
421                                 }
422                         }
423                 }
424
425                 public static void WriteLineIf (bool condition, object value)
426                 {
427                         if (condition)
428                                 WriteLine (value);
429                 }
430
431                 public static void WriteLineIf (bool condition, string message)
432                 {
433                         if (condition)
434                                 WriteLine (message);
435                 }
436
437                 public static void WriteLineIf (bool condition, object value, 
438                         string category)
439                 {
440                         if (condition)
441                                 WriteLine (value, category);
442                 }
443
444                 public static void WriteLineIf (bool condition, string message, 
445                         string category)
446                 {
447                         if (condition)
448                                 WriteLine (message, category);
449                 }
450         }
451 }
452