[bcl] Use List instead of ArrayList () in a few places.
[mono.git] / mcs / class / System / System.Diagnostics / LocalFileEventLog.cs
index f334a884f5a28ce5bda4fbc3d997ff28f8e7fbb8..c013223d08108d239bdc1c84481cc55c1d407358 100644 (file)
@@ -29,7 +29,7 @@
 //
 
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Globalization;
@@ -37,6 +37,7 @@ using System.IO;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Text;
+using System.Threading;
 
 namespace System.Diagnostics
 {
@@ -44,6 +45,9 @@ namespace System.Diagnostics
        {
                const string DateFormat = "yyyyMMddHHmmssfff";
                static readonly object lockObject = new object ();
+               FileSystemWatcher file_watcher;
+               int last_notification_index;
+               bool _notifying;
 
                public LocalFileEventLog (EventLog coreEventLog) : base (coreEventLog)
                {
@@ -64,7 +68,10 @@ namespace System.Diagnostics
 
                public override void Close ()
                {
-                       // we don't hold any unmanaged resources
+                       if (file_watcher != null) {
+                               file_watcher.EnableRaisingEvents = false;
+                               file_watcher = null; // force creation of new FileSystemWatcher
+                       }
                }
 
                public override void CreateEventSource (EventSourceCreationData sourceData)
@@ -84,7 +91,7 @@ namespace System.Diagnostics
                                // we create an event source directory named after the event log.
                                // This matches what MS does with the registry-based registration.
                                Directory.CreateDirectory (Path.Combine (logDir, sourceData.LogName));
-                               if (RunningOnLinux) {
+                               if (RunningOnUnix) {
                                        ModifyAccessPermissions (logDir, "777");
                                        ModifyAccessPermissions (logDir, "+t");
                                }
@@ -127,6 +134,52 @@ namespace System.Diagnostics
                        Close ();
                }
 
+               public override void DisableNotification ()
+               {
+                       if (file_watcher == null)
+                               return;
+                       file_watcher.EnableRaisingEvents = false;
+               }
+
+               public override void EnableNotification ()
+               {
+                       if (file_watcher == null) {
+                               string logDir = FindLogStore (CoreEventLog.Log);
+                               if (!Directory.Exists (logDir))
+                                       Directory.CreateDirectory (logDir);
+
+                               file_watcher = new FileSystemWatcher ();
+                               file_watcher.Path = logDir;
+                               file_watcher.Created += delegate (object o, FileSystemEventArgs e) {
+                                       lock (this) {
+                                               if (_notifying)
+                                                       return;
+                                               _notifying = true;
+                                       }
+
+                                       // allow for file to be finished writing
+                                       Thread.Sleep (100);
+
+                                       // Process every new entry in one notification event.
+                                       try {
+                                               while (GetLatestIndex () > last_notification_index) {
+                                                       try {
+                                                               CoreEventLog.OnEntryWritten (GetEntry (last_notification_index++));
+                                                       } catch (Exception ex) {
+                                                               // FIXME: find some proper way to output this error
+                                                               Debug.WriteLine (ex);
+                                                       }
+                                               }
+                                       } finally {
+                                               lock (this)
+                                                       _notifying = false;
+                                       }
+                               };
+                       }
+                       last_notification_index = GetLatestIndex ();
+                       file_watcher.EnableRaisingEvents = true;
+               }
+
                public override void EndInit () { }
 
                public override bool Exists (string logName, string machineName)
@@ -174,7 +227,7 @@ namespace System.Diagnostics
                                        DateFormat, CultureInfo.InvariantCulture);
                                DateTime timeWritten = File.GetLastWriteTime (file);
                                int stringNums = int.Parse (tr.ReadLine ().Substring (20));
-                               ArrayList replacementTemp = new ArrayList ();
+                               var replacementTemp = new List<string> ();
                                StringBuilder sb = new StringBuilder ();
                                while (replacementTemp.Count < stringNums) {
                                        char c = (char) tr.Read ();
@@ -185,8 +238,7 @@ namespace System.Diagnostics
                                                sb.Append (c);
                                        }
                                }
-                               string [] replacementStrings = new string [replacementTemp.Count];
-                               replacementTemp.CopyTo (replacementStrings, 0);
+                               string [] replacementStrings = replacementTemp.ToArray ();
 
                                string message = FormatMessage (source, instanceID, replacementStrings);
                                int eventID = EventLog.GetEventID (instanceID);
@@ -242,15 +294,11 @@ namespace System.Diagnostics
                        lock (lockObject) {
                                string logDir = FindLogStore (CoreEventLog.Log);
 
-                               int index = GetNewIndex ();
+                               int index = GetLatestIndex () + 1;
                                string logPath = Path.Combine (logDir, index.ToString (CultureInfo.InvariantCulture) + ".log");
                                try {
                                        using (TextWriter w = File.CreateText (logPath)) {
-#if NET_2_0
                                                w.WriteLine ("InstanceID: {0}", instanceID.ToString (CultureInfo.InvariantCulture));
-#else
-                                               w.WriteLine ("InstanceID: {0}", instanceID.ToString (CultureInfo.InvariantCulture));
-#endif
                                                w.WriteLine ("EntryType: {0}", (int) type);
                                                w.WriteLine ("Source: {0}", CoreEventLog.Source);
                                                w.WriteLine ("Category: {0}", category.ToString (CultureInfo.InvariantCulture));
@@ -292,14 +340,10 @@ namespace System.Diagnostics
                        return sourceDir;
                }
 
-               private bool RunningOnLinux {
+               private bool RunningOnUnix {
                        get {
-                               return ((int) Environment.OSVersion.Platform == 4 ||
-#if NET_2_0
-                                       Environment.OSVersion.Platform == PlatformID.Unix);
-#else
-                                       (int) Environment.OSVersion.Platform == 128);
-#endif
+                               int p = (int) Environment.OSVersion.Platform;
+                               return ((p == 4) || (p == 128) || (p == 6));
                        }
                }
 
@@ -332,17 +376,17 @@ namespace System.Diagnostics
                                string eventLogType = Environment.GetEnvironmentVariable (EventLog.EVENTLOG_TYPE_VAR);
                                if (eventLogType != null && eventLogType.Length > EventLog.LOCAL_FILE_IMPL.Length + 1)
                                        return eventLogType.Substring (EventLog.LOCAL_FILE_IMPL.Length + 1);
-                               if (RunningOnLinux) {
+                               if (RunningOnUnix) {
                                        return "/var/lib/mono/eventlog";
                                } else {
                                        return Path.Combine (Environment.GetFolderPath (
                                                Environment.SpecialFolder.CommonApplicationData),
-                                               "mono/eventlog");
+                                               "mono\\eventlog");
                                }
                        }
                }
 
-               private int GetNewIndex () {
+               private int GetLatestIndex () {
                        // our file names are one-based
                        int maxIndex = 0;
                        string[] logFiles = Directory.GetFiles (FindLogStore (CoreEventLog.Log), "*.log");
@@ -356,7 +400,7 @@ namespace System.Diagnostics
                                } catch {
                                }
                        }
-                       return ++maxIndex;
+                       return maxIndex;
                }
 
                private static void ModifyAccessPermissions (string path, string permissions)
@@ -382,5 +426,28 @@ namespace System.Diagnostics
                        }
                        p.Close ();
                }
+
+               public override OverflowAction OverflowAction {
+                       get { return OverflowAction.DoNotOverwrite; }
+               }
+
+               public override int MinimumRetentionDays {
+                       get { return int.MaxValue; }
+               }
+
+               public override long MaximumKilobytes {
+                       get { return long.MaxValue; }
+                       set { throw new NotSupportedException ("This EventLog implementation does not support setting max kilobytes policy"); }
+               }
+
+               public override void ModifyOverflowPolicy (OverflowAction action, int retentionDays)
+               {
+                       throw new NotSupportedException ("This EventLog implementation does not support modifying overflow policy");
+               }
+
+               public override void RegisterDisplayName (string resourceFile, long resourceId)
+               {
+                       throw new NotSupportedException ("This EventLog implementation does not support registering display name");
+               }
        }
 }