changeset 93:dc4942d09e74 v2

improved tracing added the application components container MTComponentContainer.AppContainer
author cin
date Thu, 23 Oct 2014 01:13:57 +0400
parents 4c0e5ef99986
children a43745f81f10
files .hgignore Implab.mono.sln Implab/Diagnostics/OperationContext.cs Implab/Diagnostics/TraceContext.cs Implab/Diagnostics/TraceEvent.cs Implab/Diagnostics/TraceEventType.cs Implab/IComponentContainer.cs Implab/Implab.csproj Implab/MTComponentContainer.cs Implab/Parallels/DispatchPool.cs Implab/Parallels/MTQueue.cs MonoPlay/MonoPlay.csproj MonoPlay/Program.cs MonoPlay/Properties/AssemblyInfo.cs
diffstat 14 files changed, 217 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Oct 22 18:37:56 2014 +0400
+++ b/.hgignore	Thu Oct 23 01:13:57 2014 +0400
@@ -13,3 +13,4 @@
 _ReSharper.Implab/
 Implab.Diagnostics.Interactive/bin/
 Implab.Diagnostics.Interactive/obj/
+MonoPlay/bin/
--- a/Implab.mono.sln	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab.mono.sln	Thu Oct 23 01:13:57 2014 +0400
@@ -16,6 +16,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test.mono", "Implab.Test\Implab.Test.mono.csproj", "{2BD05F84-E067-4B87-9477-FDC2676A21C6}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoPlay", "MonoPlay\MonoPlay.csproj", "{15DD7123-D504-4627-8B4F-D00C7F04D033}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -32,22 +34,30 @@
 		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
 		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Release 4.5|Any CPU.Build.0 = Release|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{15DD7123-D504-4627-8B4F-D00C7F04D033}.Release|Any CPU.Build.0 = Release|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.Build.0 = Release|Any CPU
-		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
 		{2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
 		{2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
 		{2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -64,20 +74,12 @@
 		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
 		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
 	EndGlobalSection
 	GlobalSection(MonoDevelopProperties) = preSolution
-		StartupItem = Implab\Implab.csproj
+		StartupItem = MonoPlay\MonoPlay.csproj
 		Policies = $0
 		$0.CSharpFormattingPolicy = $1
 		$1.IndentSwitchBody = True
--- a/Implab/Diagnostics/OperationContext.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Diagnostics/OperationContext.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -28,22 +28,32 @@
                     m_current = m_current.Parent;
                 else if (m_ownership)
                     m_current = LogicalOperation.EMPTY;
-                else
+                else {
+                    TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context");
                     detached = LogicalOperation.EMPTY;
+                }
+            } else {
+                TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context");
             }
-            TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context");
+
             return detached;
         }
 
         public void EndLogicalOperation() {
             if (m_current != m_initial) {
                 m_current = m_current.Parent;
-            } else if (m_current != null && m_ownership) {
-                m_current = null;
+            } else if (m_current != LogicalOperation.EMPTY && m_ownership) {
+                m_current = LogicalOperation.EMPTY;
             } else {
                 TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context");
             }
         }
+
+        public void Leave() {
+
+            if ((m_ownership && m_current != LogicalOperation.EMPTY) || (!m_ownership && m_current != m_initial) )
+                TraceLog.TraceWarning("Trying to leave unfinished logical operation {0}", m_current.Name);
+        }
     }
 }
 
--- a/Implab/Diagnostics/TraceContext.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Diagnostics/TraceContext.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -41,35 +41,36 @@
         }
 
         public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) {
-            // TODO Emit event
+            LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Attach, String.Format("{0} -> [{1}]", operation.Name, m_threadId)));
             m_stack.Push(m_current);
             m_current = new OperationContext(operation, takeOwnership);
         }
 
         public void StartLogicalOperation(string name) {
             m_current.BeginLogicalOperation(name);
+            LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationStarted, String.Format("+{0}",CurrentOperation.Name)));
         }
 
         public void StartLogicalOperation() {
-            // TODO Emit Event
-            m_current.BeginLogicalOperation(String.Empty);
+            StartLogicalOperation(String.Empty);
         }
 
         public void EndLogicalOperation() {
-            // TODO Emit event
+            LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",CurrentOperation.Name, CurrentOperation.Duration)));
             m_current.EndLogicalOperation();
         }
 
         public LogicalOperation DetachLogicalOperation() {
-            // TODO Emit event
-            return m_current.DetachLogicalOperation();
+            var op = m_current.DetachLogicalOperation();
+            LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Detach, String.Format("[{0}] -> {1}", m_threadId, op.Name)));
+            return op;
         }
 
         public void Leave() {
-            // TODO Emit event
-            if (m_stack.Count > 0)
+            if (m_stack.Count > 0) {
+                m_current.Leave();
                 m_current = m_stack.Pop();
-            else {
+            } else {
                 TraceLog.TraceWarning("Attemtp to leave the last operation context");
                 m_current = OperationContext.EMPTY;
             }
--- a/Implab/Diagnostics/TraceEvent.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Diagnostics/TraceEvent.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -1,7 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 
 namespace Implab.Diagnostics {
     public class TraceEvent {
@@ -21,10 +18,7 @@
         }
 
         public override string ToString() {
-            if (EventType == TraceEventType.Information)
-                return Message;
-            else
-                return String.Format("{0}: {1}", EventType, Message);
+            return EventType == TraceEventType.Information ? Message : String.Format("{0}: {1}", EventType, Message);
         }
 
         public static TraceEvent Create(TraceEventType type, string format, params object[] args) {
--- a/Implab/Diagnostics/TraceEventType.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Diagnostics/TraceEventType.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -11,9 +11,7 @@
         Error,
         OperationStarted,
         OperationCompleted,
-        Fork,
         Attach,
         Detach,
-        Created
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/IComponentContainer.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -0,0 +1,8 @@
+using System;
+
+namespace Implab {
+    public interface IComponentContainer {
+        void Add(IDisposable component);
+    }
+}
+
--- a/Implab/Implab.csproj	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Implab.csproj	Thu Oct 23 01:13:57 2014 +0400
@@ -7,6 +7,8 @@
     <OutputType>Library</OutputType>
     <RootNamespace>Implab</RootNamespace>
     <AssemblyName>Implab</AssemblyName>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -145,6 +147,8 @@
     <Compile Include="Diagnostics\LogEventArgs.cs" />
     <Compile Include="Diagnostics\LogEventArgsT.cs" />
     <Compile Include="Diagnostics\Extensions.cs" />
+    <Compile Include="IComponentContainer.cs" />
+    <Compile Include="MTComponentContainer.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/MTComponentContainer.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -0,0 +1,48 @@
+using System;
+using Implab.Parallels;
+using System.Threading;
+
+namespace Implab {
+    public class MTComponentContainer : IComponentContainer, IDisposable {
+        static readonly MTComponentContainer _appContainer;
+
+        static MTComponentContainer() {
+            _appContainer = new MTComponentContainer();
+            AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
+        }
+
+        public static MTComponentContainer AppContainer {
+            get {
+                return _appContainer;
+            }
+        }
+
+        bool m_disposed;
+        readonly MTQueue<IDisposable> m_components = new MTQueue<IDisposable>();
+
+        public void Add(IDisposable item) {
+            Safe.ArgumentNotNull(item, "item");
+            Thread.MemoryBarrier();
+            if (m_disposed) {
+                item.Dispose();
+            } else {
+                m_components.Enqueue(item);
+                if (m_disposed && m_components.TryDequeue(out item))
+                    item.Dispose();
+            }
+        }
+
+        public void Dispose() {
+            m_disposed = true;
+            IDisposable item;
+            while (m_components.TryDequeue(out item))
+                item.Dispose();
+        }
+
+        static void HandleProcessExit (object sender, EventArgs e)
+        {
+            _appContainer.Dispose();
+        }
+    }
+}
+
--- a/Implab/Parallels/DispatchPool.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Parallels/DispatchPool.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -7,9 +7,9 @@
         readonly int m_maxThreadsLimit;
         readonly int m_releaseTimeout = 1000; // the timeout while the working thread will wait for the new tasks before exit
 
-        int m_threads = 0; // the current size of the pool
-        int m_maxRunningThreads = 0; // the meximum reached size of the pool
-        int m_exit = 0; // the pool is going to shutdown, all unused workers are released
+        int m_threads; // the current size of the pool
+        int m_maxRunningThreads; // the meximum reached size of the pool
+        int m_exit; // the pool is going to shutdown, all unused workers are released
 
         readonly object m_signal = new object(); // used to pulse waiting threads
 
--- a/Implab/Parallels/MTQueue.cs	Wed Oct 22 18:37:56 2014 +0400
+++ b/Implab/Parallels/MTQueue.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
+using System.Threading;
 
 namespace Implab.Parallels {
     public class MTQueue<T> {
@@ -34,7 +30,7 @@
 
         public bool TryDequeue(out T value) {
             Node first;
-            Node next = null;
+            Node next;
             value = default(T);
 
             Thread.MemoryBarrier();
@@ -64,11 +60,10 @@
                     Interlocked.CompareExchange(ref m_first, null, first);
                     break;
 
-                } else {
-                    if (first == Interlocked.CompareExchange(ref m_first, next, first))
-                        // head succesfully updated
-                        break;
                 }
+                if (first == Interlocked.CompareExchange(ref m_first, next, first))
+                    // head succesfully updated
+                    break;
             } while (true);
 
             value = first.value;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MonoPlay/MonoPlay.csproj	Thu Oct 23 01:13:57 2014 +0400
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{15DD7123-D504-4627-8B4F-D00C7F04D033}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>MonoPlay</RootNamespace>
+    <AssemblyName>MonoPlay</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Implab\Implab.csproj">
+      <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
+      <Name>Implab</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MonoPlay/Program.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -0,0 +1,31 @@
+using System;
+using Implab.Diagnostics;
+using Implab.Parallels;
+using Implab;
+
+namespace MonoPlay {
+    class MainClass {
+        public static void Main(string[] args) {
+            var listener = new ConsoleTraceListener(true);
+            listener.Subscribe<TraceEvent>();
+
+            MTComponentContainer.AppContainer.Add(listener);
+
+            TraceLog.StartLogicalOperation("program");
+
+            Console.WriteLine("Hello World!");
+
+            TraceLog.StartLogicalOperation("async");
+            AsyncPool.Invoke(() => {
+                TraceLog.TraceInformation("Hello async");
+                TraceLog.StartLogicalOperation();
+                return 0;
+            })
+                .EndLogicalOperation()
+                .Join();
+
+            TraceLog.EndLogicalOperation();
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MonoPlay/Properties/AssemblyInfo.cs	Thu Oct 23 01:13:57 2014 +0400
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("MonoPlay")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("sergey")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+