Merge pull request #3809 from lateralusX/jlorenss/win-api-family-support-cleanup
authorJohan Lorensson <lateralusx.github@gmail.com>
Fri, 11 Nov 2016 10:43:49 +0000 (11:43 +0100)
committerGitHub <noreply@github.com>
Fri, 11 Nov 2016 10:43:49 +0000 (11:43 +0100)
Build mono runtime under none desktop Windows API family, adjustments and cleanup.

109 files changed:
.gitmodules
Makefile.am
eglib/src/gfile-unix.c
eglib/src/glib.h
external/bockbuild [new submodule]
external/nunit-lite
mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2DataReader.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/TargetTest.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/System.ServiceProcess/System.ServiceProcess/Win32ServiceController.cs
mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerTest.cs
mcs/class/System.XML/System.Xml.Serialization/TypeData.cs
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs
mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs
mcs/class/System/System.Diagnostics/Process.cs
mcs/class/System/System.Net.Sockets/TcpListener.platformnotsupported.cs
mcs/class/System/System.Net.Sockets/UdpClient.platformnotsupported.cs
mcs/class/System/System.Net/HttpListener.platformnotsupported.cs
mcs/class/System/System.Net/HttpListenerContext.platformnotsupported.cs
mcs/class/System/System.Net/HttpWebRequest.platformnotsupported.cs
mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/Environment.cs
mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs
mono/btls/btls-time64.c
mono/io-layer/Makefile.am
mono/io-layer/context.c [deleted file]
mono/io-layer/context.h [deleted file]
mono/io-layer/uglify.h
mono/io-layer/wapi-remap.h
mono/io-layer/wapi.h
mono/metadata/appdomain.c
mono/metadata/class-accessors.c
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/custom-attrs.c
mono/metadata/icall.c
mono/metadata/loader.c
mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/security-core-clr.c
mono/metadata/sgen-stw.c
mono/metadata/sre.c
mono/metadata/threads.c
mono/metadata/verify.c
mono/metadata/w32handle.c
mono/metadata/w32handle.h
mono/metadata/w32process-unix.c
mono/mini/aot-compiler.c
mono/mini/debugger-agent.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-x86.c
mono/mini/image-writer.c
mono/mini/main.c
mono/mini/mini-arm64.c
mono/mini/mini-generic-sharing.c
mono/mini/mini-ppc.h
mono/sgen/sgen-debug.c
mono/tests/Makefile.am
mono/tests/thread-suspend-selfsuspended.cs [new file with mode: 0644]
mono/utils/mono-context.h
mono/utils/mono-threads-state-machine.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
mono/utils/os-event-unix.c
mono/utils/os-event-win32.c
mono/utils/os-event.h
mono/utils/win64.asm
packaging/MacSDK/__init__.py [new file with mode: 0644]
packaging/MacSDK/fsharp.py [new file with mode: 0644]
packaging/MacSDK/gdk-pixbuf/0001-pixbuf-Add-getter-setter-for-the-2x-variants.patch [new file with mode: 0644]
packaging/MacSDK/gdk-pixbuf/0001-pixbuf-load-2x-variants-as-pixbuf-gobject-data.patch [new file with mode: 0644]
packaging/MacSDK/gtkrc [new file with mode: 0644]
packaging/MacSDK/ironlangs.py [new file with mode: 0644]
packaging/MacSDK/libgdiplus.py [new file with mode: 0644]
packaging/MacSDK/mono-basic.py [new file with mode: 0644]
packaging/MacSDK/mono-llvm.py [new file with mode: 0644]
packaging/MacSDK/mono.py [new file with mode: 0644]
packaging/MacSDK/msbuild.py [new file with mode: 0644]
packaging/MacSDK/nuget.py [new file with mode: 0644]
packaging/MacSDK/packaging/Info.plist [new file with mode: 0644]
packaging/MacSDK/packaging/Info_sdk.plist [new file with mode: 0644]
packaging/MacSDK/packaging/mdk_blacklist.sh [new file with mode: 0755]
packaging/MacSDK/packaging/resources/License.rtf [new file with mode: 0644]
packaging/MacSDK/packaging/resources/ReadMe.rtf [new file with mode: 0644]
packaging/MacSDK/packaging/resources/Welcome.rtf [new file with mode: 0644]
packaging/MacSDK/packaging/resources/distribution.xml [new file with mode: 0644]
packaging/MacSDK/packaging/resources/postinstall [new file with mode: 0755]
packaging/MacSDK/packaging/resources/version.plist [new file with mode: 0644]
packaging/MacSDK/packaging/resources/whitelist.txt [new file with mode: 0644]
packaging/MacSDK/packaging/uninstallMono.sh [new file with mode: 0755]
packaging/MacSDK/patches/find-unused-patches.sh [new file with mode: 0755]
packaging/MacSDK/patches/mcs-pkgconfig.patch [new file with mode: 0644]
packaging/MacSDK/pcl-reference-assemblies.py [new file with mode: 0644]
packaging/MacSDK/profile.py [new file with mode: 0755]
packaging/MacSDK/sqlite.py [new file with mode: 0644]
packaging/MacSDK/xamarin-gtk-theme.py [new file with mode: 0644]
packaging/MacSDK/xsp.py [new file with mode: 0644]
packaging/MacSDKRelease/mono-extensions.py [new file with mode: 0644]
packaging/MacSDKRelease/packaging [new symlink]
packaging/MacSDKRelease/profile.py [new file with mode: 0755]
scripts/ci/run-test-default.sh
tools/offsets-tool/Makefile
tools/offsets-tool/MonoAotOffsetsDumper.cs

index 1c8f76e0107dae1e948de7280f293bcd110ef7b1..337fbe06c0b3ca4df54eaf18e0818d83c718667b 100644 (file)
@@ -46,3 +46,6 @@
 [submodule "external/corefx"]
        path = external/corefx
        url = git://github.com/mono/corefx.git
+[submodule "external/bockbuild"]
+       path = external/bockbuild
+       url = git://github.com/mono/bockbuild.git
index aaffb9842ba9dbe36090cead00afe0d1ebe1232d..74707da14109c704302a1f7eab547e79082b812e 100644 (file)
@@ -49,6 +49,9 @@ dist-hook:
 # Disable this for now because it is very slow and causes wrench to timeout:
 #      test ! -d $(GIT_DIR) || ./scripts/commits-to-changelog.py --root=$(distdir) last-commit-with-compulsory-changelog-entry
 
+mac-sdk-package:
+       external/bockbuild/bb MacSDK --package
+
 pkgconfigdir = $(libdir)/pkgconfig
 noinst_DATA = mono-uninstalled.pc
 DISTCLEANFILES= mono-uninstalled.pc
index 4e17a089b5444b040cb92ed2562f4df52d365eb6..9c34d8756930f4fa7e898995c1d02329843f1be9 100644 (file)
@@ -78,3 +78,11 @@ g_file_test (const gchar *filename, GFileTest test)
        }
        return FALSE;
 }
+
+gchar *
+g_mkdtemp (char *tmp_template)
+{
+       char *template_copy = g_strdup (tmp_template);
+
+       return mkdtemp (template_copy);
+}
index 1bc8506310edfa9ea570c94ccbed620266ead00c..8ceec487041d6bb7c3a2a72d3f8e85cfd2ecaa78 100644 (file)
@@ -887,11 +887,7 @@ gboolean   g_file_test (const gchar *filename, GFileTest test);
 #define g_ascii_strtod strtod
 #define g_ascii_isalnum isalnum
 
-#ifdef WIN32
 gchar *g_mkdtemp (gchar *tmpl);
-#else
-#define g_mkdtemp mkdtemp
-#endif
 
 /*
  * Pattern matching
diff --git a/external/bockbuild b/external/bockbuild
new file mode 160000 (submodule)
index 0000000..cc441a6
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit cc441a606b409159d1704d5ee78c88e06e0d5332
index dda48cd0343bddac6b3faf0c0498b680468cc3fd..670081afaf2a5662ec6471a7e2603c7ca6e8edbc 160000 (submodule)
@@ -1 +1 @@
-Subproject commit dda48cd0343bddac6b3faf0c0498b680468cc3fd
+Subproject commit 670081afaf2a5662ec6471a7e2603c7ca6e8edbc
index a5761603e4d5b5a93b95a041108ea08e76a32a6f..0c22a91db06397e9d339d05bc43f82790e7eb8b8 100644 (file)
@@ -462,14 +462,16 @@ namespace IBM.Data.DB2
                        for(int i = 0; i < columnInfo.Length; i++)\r
                        {\r
                                short sqlRet;\r
-                               short strlen;\r
-                               int numericAttribute;\r
-\r
-                               sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, sb, (short)sb.Capacity, out strlen, out numericAttribute);\r
+                               short strlen = 0;\r
+                               int numericAttribute = 0;\r
+                               \r
+                               sb.Clear();\r
+                               sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_COLUMN_NAME, sb, (short)sb.Capacity, out strlen, out numericAttribute);\r
                                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");\r
                                columnInfo[i].Colname = sb.ToString();\r
                                columnsNames[columnInfo[i].Colname.ToUpper()] = i;\r
-\r
+                               \r
+                               strlen = 0;\r
                                sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_CONCISE_TYPE, sb, (short)sb.Capacity, out strlen, out columnInfo[i].Sqltype);\r
                                DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");\r
 \r
index f663120bf798730223c944db359caa7873771dc5..82af83b15232988b1fd1d50b1b18e80d2bc09536 100644 (file)
@@ -226,6 +226,14 @@ namespace Microsoft.Build.BuildEngine {
                public void SetMetadata (string metadataName,
                                         string metadataValue,
                                         bool treatMetadataValueAsLiteral)
+               {
+                       SetMetadata (metadataName, metadataValue, treatMetadataValueAsLiteral, false);
+               }
+
+               void SetMetadata (string metadataName,
+                                        string metadataValue,
+                                        bool treatMetadataValueAsLiteral,
+                                        bool fromDynamicItem)
                {
                        if (metadataName == null)
                                throw new ArgumentNullException ("metadataName");
@@ -251,9 +259,11 @@ namespace Microsoft.Build.BuildEngine {
                        } else if (HasParentItem) {
                                if (parent_item.child_items.Count > 1)
                                        SplitParentItem ();
-                               parent_item.SetMetadata (metadataName, metadataValue, treatMetadataValueAsLiteral);
+                               parent_item.SetMetadata (metadataName, metadataValue, treatMetadataValueAsLiteral, fromDynamicItem);
                        }
-                       if (FromXml || HasParentItem) {
+
+                       // We don't want to reevalute the project for dynamic items
+                       if (!fromDynamicItem && !IsDynamic && (FromXml || HasParentItem)) {
                                parent_item_group.ParentProject.MarkProjectAsDirty ();
                                parent_item_group.ParentProject.NeedToReevaluate ();
                        }
@@ -374,7 +384,7 @@ namespace Microsoft.Build.BuildEngine {
                                        continue;
                                
                                foreach (string name in evaluatedMetadata.Keys) {
-                                       item.SetMetadata (name, (string)evaluatedMetadata [name]);
+                                       item.SetMetadata (name, (string)evaluatedMetadata [name], false, IsDynamic);
                                }
 
                                AddAndRemoveMetadata (project, item);
index 459bb66e6d5cd3cde9d2007433d0e8aaecb1a480..8f2aa2e7b28daf2b2f4f41ae052bae1b3097e233 100644 (file)
@@ -698,6 +698,33 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                </Project>", "D");
                }
 
+               [Test]
+               public void ItemGroupInsideTarget_UpdateMetadata ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                                       <ItemGroup>
+                                               <ProjectReference Include='xyz'/>
+                                       </ItemGroup>
+
+                                       <Target Name='Main' DependsOnTargets='CreateBar'>
+                                               <Message Text='Before: $(Bar)'/>
+                                               <ItemGroup>
+                                                       <ProjectReference>
+                                                               <AdditionalProperties>A=b</AdditionalProperties>
+                                                       </ProjectReference>
+                                               </ItemGroup>
+                                               <Message Text='After: $(Bar)'/>
+                                       </Target>
+
+                                       <Target Name='CreateBar'>
+                                               <PropertyGroup>
+                                                       <Bar>Bar01</Bar>
+                                               </PropertyGroup>
+                                       </Target>
+                               </Project>", 2, "Before: Bar01", "After: Bar01");
+               }
+
                [Test]
                public void ItemGroupInsideTarget_Batching ()
                {
index 532a6b207a1183216167b4439aed53d7db5e1465..ac3b91b9247f3973b753be0dfeb035ab3aead757 100644 (file)
@@ -430,6 +430,7 @@ public class Tests : TestsBase, ITest2
                ss_recursive2 (1);
                ss_recursive_chaotic ();
                ss_fp_clobber ();
+               ss_no_frames ();
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
@@ -679,6 +680,25 @@ public class Tests : TestsBase, ITest2
        public static void ss_fp_clobber_2 (double d) {
        }
 
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_no_frames () {
+               Action a = ss_no_frames_2;
+               var ar = a.BeginInvoke (null, null);
+               ar.AsyncWaitHandle.WaitOne ();
+               // Avoid waiting every time this runs
+               if (static_i == 56)
+                       Thread.Sleep (200);
+               ss_no_frames_3 ();
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_no_frames_2 () {
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_no_frames_3 () {
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static bool is_even (int i) {
                return i % 2 == 0;
index af994790ea00b44e9eedcf6e4d6af2467ee3e232..c07fdd26d21034e41c42c6851a344608afae0b7f 100644 (file)
@@ -906,6 +906,28 @@ public class DebuggerTests
                req.Disable ();
        }
 
+       [Test]
+       public void SingleSteppingNoFrames () {
+               //
+               // Test what happens when starting a single step operation on a thread
+               // with no managed frames
+               //
+               // Run a delegate on a tp thread
+               var e = run_until ("ss_no_frames_2");
+
+               var this_type = e.Thread.GetFrames ()[0].Method.DeclaringType;
+               this_type.SetValue (this_type.GetField ("static_i"), vm.CreateValue (56));
+
+               var thread = e.Thread;
+               var e2 = run_until ("ss_no_frames_3");
+               // The tp thread should be idle now
+               step_req = vm.CreateStepRequest (thread);
+               step_req.Depth = StepDepth.Over;
+               AssertThrows<Exception> (delegate {
+                       step_req.Enable ();
+                       });
+       }
+
        [Test]
        public void MethodEntryExit () {
                run_until ("single_stepping");
index fee6147202eec4b96a90408dce6fe7519b55cfc1..11a62dd6529ccb39aaf2717850500d883de7f0a6 100644 (file)
@@ -390,17 +390,17 @@ namespace System.ServiceProcess
                                                        throw new Win32Exception (err);
                                                }
                                        } else {
-                                               int iPtr = buffer.ToInt32 ();
+                                               IntPtr iPtr = buffer;
 
                                                services = new ServiceController [servicesReturned];
                                                for (int i = 0; i < servicesReturned; i++) {
                                                        ENUM_SERVICE_STATUS serviceStatus = (ENUM_SERVICE_STATUS) Marshal.PtrToStructure (
-                                                               new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS));
+                                                               iPtr, typeof (ENUM_SERVICE_STATUS));
                                                        // TODO: use internal ctor that takes displayname too ?
                                                        services [i] = new ServiceController (serviceStatus.pServiceName,
                                                                machineName);
                                                        // move on to the next services
-                                                       iPtr += ENUM_SERVICE_STATUS.SizeOf;
+                                                       iPtr = IntPtr.Add(iPtr, ENUM_SERVICE_STATUS.SizeOf);
                                                }
 
                                                // we're done, so exit the loop
@@ -611,17 +611,17 @@ namespace System.ServiceProcess
                                                        throw new Win32Exception (err);
                                                }
                                        } else {
-                                               int iPtr = buffer.ToInt32 ();
+                                               IntPtr iPtr = buffer;
 
                                                services = new ServiceController [servicesReturned];
                                                for (int i = 0; i < servicesReturned; i++) {
                                                        ENUM_SERVICE_STATUS_PROCESS serviceStatus = (ENUM_SERVICE_STATUS_PROCESS) Marshal.PtrToStructure (
-                                                               new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS_PROCESS));
+                                                               iPtr, typeof (ENUM_SERVICE_STATUS_PROCESS));
                                                        // TODO: use internal ctor that takes displayname too
                                                        services [i] = new ServiceController (serviceStatus.pServiceName,
                                                                machineName);
                                                        // move on to the next services
-                                                       iPtr += ENUM_SERVICE_STATUS_PROCESS.SizeOf;
+                                                       iPtr = IntPtr.Add(iPtr, ENUM_SERVICE_STATUS_PROCESS.SizeOf);
                                                }
 
                                                // we're done, so exit the loop
index 8f5b8f6000b50c1927c8e79c4b36e834fa09ca5b..9f5ae98d470b75b5c838143b69fda659de97fce2 100644 (file)
@@ -31,6 +31,7 @@
 // - Start
 
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.ServiceProcess;
 using TimeoutException = System.ServiceProcess.TimeoutException;
@@ -42,6 +43,58 @@ namespace MonoTests.System.ServiceProcess
        [TestFixture]
        public class ServiceControllerTest
        {
+               class ServiceInfo
+               {
+                       public string ServiceName;
+                       public string DisplayName;
+                       public ServiceType ServiceType = ServiceType.Win32ShareProcess;
+                       public string[] Dependents = new string[] {};
+                       public string[] DependedOn = new string[] {};
+               }
+
+               static ServiceInfo DISK_DRIVER_SERVICE = new ServiceInfo { ServiceName = "disk", DisplayName = "Disk Driver", ServiceType = ServiceType.KernelDriver };
+               static ServiceInfo ROUTING_AND_REMOTE_ACCESS_SERVICE = new ServiceInfo { ServiceName = "RemoteAccess", DisplayName = "Routing and Remote Access", DependedOn = new [] { "bfe", "http", "rasman", "rpcss" } };
+               static ServiceInfo SECONDARY_LOGON_SERVICE = new ServiceInfo { ServiceName = "seclogon", DisplayName = "Secondary Logon", Dependents = new [] { "te.service" } };
+               static ServiceInfo SECURITY_ACCOUNTS_MANAGER_SERVICE = new ServiceInfo { ServiceName = "SamSs", DisplayName = "Security Accounts Manager", Dependents = new [] { "browser", "ktmrm", "lanmanserver", "msdtc" }, DependedOn = new [] { "rpcss" } };
+               static ServiceInfo WINDOWS_IMAGE_ACQUISITION_SERVICE = new ServiceInfo { ServiceName = "stisvc", DisplayName = "Windows Image Acquisition (WIA)", ServiceType = ServiceType.Win32OwnProcess, DependedOn = new [] { "rpcss" } };
+               static ServiceInfo WINDOWS_SEARCH_SERVICE = new ServiceInfo { ServiceName = "WSearch", DisplayName = "Windows Search", ServiceType = ServiceType.Win32OwnProcess, Dependents = new [] { "wmpnetworksvc", "workfolderssvc" }, DependedOn = new [] { "rpcss" } };
+               static ServiceInfo WINDOWS_TIME_SERVICE = new ServiceInfo { ServiceName = "W32Time", DisplayName = "Windows Time" };
+               static ServiceInfo WINDOWS_UPDATE_SERVICE = new ServiceInfo { ServiceName = "wuauserv", DisplayName = "Windows Update", DependedOn = new [] { "rpcss" } };
+               static ServiceInfo WORKSTATION_SERVICE = new ServiceInfo { ServiceName = "LanmanWorkstation", DisplayName = "Workstation", Dependents = new [] { "browser", "netlogon", "sessionenv" }, DependedOn = new [] { "bowser", "mrxsmb20", "nsi" } };
+
+               // A service which is expected to be disabled by default on all supported Windows versions.
+               static ServiceInfo DISABLED_SERVICE = ROUTING_AND_REMOTE_ACCESS_SERVICE;
+               // A service which is running by default and can be stopped/paused by the current user when running with admin rights.
+               static ServiceInfo CONTROLLABLE_SERVICE = WINDOWS_IMAGE_ACQUISITION_SERVICE;
+               // A service which cannot be stopped/paused.
+               static ServiceInfo UNCONTROLLABLE_SERVICE = SECURITY_ACCOUNTS_MANAGER_SERVICE;
+               // A service with ServiceType == KernelDriver
+               static ServiceInfo KERNEL_SERVICE = DISK_DRIVER_SERVICE;
+               // A service with ServiceType == Win32ShareProcess.
+               static ServiceInfo SHARE_PROCESS_SERVICE = WORKSTATION_SERVICE;
+
+               static ServiceInfo SERVICE_1_WITH_DEPENDENTS_AND_DEPENDED_ON = SECURITY_ACCOUNTS_MANAGER_SERVICE;
+               static ServiceInfo SERVICE_2_WITH_DEPENDENTS_AND_DEPENDED_ON = WINDOWS_SEARCH_SERVICE;
+               static ServiceInfo SERVICE_3_WITH_DEPENDENTS_AND_DEPENDED_ON = WORKSTATION_SERVICE;
+
+               static ServiceInfo SERVICE_WITH_MANY_DEPENDENTS = WORKSTATION_SERVICE;
+               static ServiceInfo SERVICE_WITH_ONE_DEPENDENT = SECONDARY_LOGON_SERVICE;
+               static ServiceInfo SERVICE_WITH_NO_DEPENDENTS = WINDOWS_TIME_SERVICE;
+
+               static ServiceInfo SERVICE_WITH_MANY_DEPENDED_ON = WORKSTATION_SERVICE;
+               static ServiceInfo SERVICE_WITH_ONE_DEPENDED_ON = WINDOWS_UPDATE_SERVICE;
+               static ServiceInfo SERVICE_WITH_NO_DEPENDED_ON = WINDOWS_TIME_SERVICE;
+
+               [TestFixtureSetUp]
+               public void FixtureSetUp ()
+               {
+                       try {
+                               EnsureServiceIsRunning (new ServiceController (CONTROLLABLE_SERVICE.ServiceName));
+                       } catch {
+                               Assert.Ignore ($"Failed to start the service '{CONTROLLABLE_SERVICE.DisplayName}'. Ensure you are running the tests with admin privileges.");
+                       }
+               }
+
                [Test]
                public void Constructor1 ()
                {
@@ -164,7 +217,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("lanmanworkstation");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName);
 
                        Assert.IsTrue (sc.CanPauseAndContinue, "#A1");
                        Assert.IsTrue (sc.CanShutdown, "#B1");
@@ -175,10 +228,10 @@ namespace MonoTests.System.ServiceProcess
 
                        ServiceController [] dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#D1");
-                       Assert.IsTrue (dependentServices.Length > 1, "#D2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.Dependents, ServiceNames (dependentServices), "#D2");
 
                        Assert.IsNotNull (sc.DisplayName, "#E1");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#E2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.DisplayName, sc.DisplayName, "#E2");
 
                        Assert.IsNotNull (sc.MachineName, "#F1");
                        Assert.AreEqual (".", sc.MachineName, "#F2");
@@ -186,13 +239,13 @@ namespace MonoTests.System.ServiceProcess
                        sc.Refresh ();
 
                        Assert.IsNotNull (sc.ServiceName, "#G1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.ServiceName, sc.ServiceName, "#G2");
 
                        ServiceController [] servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#H1");
-                       Assert.AreEqual (0, servicesDependedOn.Length, "#H2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.DependedOn, ServiceNames (servicesDependedOn), "#H2");
 
-                       Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#I1");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.ServiceType, sc.ServiceType, "#I1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#J1");
                }
 
@@ -219,7 +272,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("workstation");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.DisplayName);
 
                        Assert.IsTrue (sc.CanPauseAndContinue, "#A1");
                        Assert.IsTrue (sc.CanShutdown, "#B1");
@@ -249,7 +302,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("lanmanworkstation");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName);
 
                        Assert.IsTrue (sc.CanPauseAndContinue, "#A1");
                        Assert.IsTrue (sc.CanShutdown, "#B1");
@@ -262,7 +315,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("lanmanworkstation",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                Environment.MachineName);
 
                        Assert.IsTrue (sc.CanPauseAndContinue, "#A1");
@@ -274,10 +327,10 @@ namespace MonoTests.System.ServiceProcess
 
                        ServiceController [] dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#D1");
-                       Assert.IsTrue (dependentServices.Length > 1, "#D2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.Dependents, ServiceNames (dependentServices), "#D2");
 
                        Assert.IsNotNull (sc.DisplayName, "#E1");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#E2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.DisplayName, sc.DisplayName, "#E2");
 
                        Assert.IsNotNull (sc.MachineName, "#F1");
                        Assert.AreEqual (Environment.MachineName, sc.MachineName, "#F2");
@@ -285,13 +338,13 @@ namespace MonoTests.System.ServiceProcess
                        sc.Refresh ();
 
                        Assert.IsNotNull (sc.ServiceName, "#G1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.ServiceName, sc.ServiceName, "#G2");
 
                        ServiceController [] servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#H1");
-                       Assert.AreEqual (0, servicesDependedOn.Length, "#H2");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.DependedOn, ServiceNames (servicesDependedOn), "#H2");
 
-                       Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#I1");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.ServiceType, sc.ServiceType, "#I1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#J1");
                }
 
@@ -299,7 +352,7 @@ namespace MonoTests.System.ServiceProcess
                public void Constructor3_MachineName_Empty ()
                {
                        try {
-                               new ServiceController ("alerter", string.Empty);
+                               new ServiceController (CONTROLLABLE_SERVICE.ServiceName, string.Empty);
                                Assert.Fail ("#1");
                        } catch (ArgumentException ex) {
                                // MachineName value  is invalid
@@ -316,7 +369,7 @@ namespace MonoTests.System.ServiceProcess
                public void Constructor3_MachineName_Null ()
                {
                        try {
-                               new ServiceController ("alerter", null);
+                               new ServiceController (CONTROLLABLE_SERVICE.ServiceName, null);
                                Assert.Fail ("#1");
                        } catch (ArgumentException ex) {
                                // MachineName value  is invalid
@@ -369,11 +422,11 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsTrue (sc.CanPauseAndContinue, "#1");
-                       sc.ServiceName = "SamSs";
+                       sc.ServiceName = UNCONTROLLABLE_SERVICE.ServiceName;
                        Assert.IsFalse (sc.CanPauseAndContinue, "#2");
-                       sc.DisplayName = "Workstation";
+                       sc.DisplayName = CONTROLLABLE_SERVICE.DisplayName;
                        Assert.IsTrue (sc.CanPauseAndContinue, "#3");
                        sc.MachineName = "doesnotexist";
                        try {
@@ -403,7 +456,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                bool canPauseAndContinue = sc.CanPauseAndContinue;
@@ -432,7 +485,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanPauseAndContinue);
                }
 
@@ -470,7 +523,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanPauseAndContinue);
                }
 
@@ -480,7 +533,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1");
                        Assert.IsTrue (sc.CanPauseAndContinue, "#2");
                }
@@ -491,8 +544,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -528,8 +581,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -584,11 +637,11 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsTrue (sc.CanShutdown, "#1");
-                       sc.ServiceName = "SamSs";
+                       sc.ServiceName = UNCONTROLLABLE_SERVICE.ServiceName;
                        Assert.IsFalse (sc.CanShutdown, "#2");
-                       sc.DisplayName = "Workstation";
+                       sc.DisplayName = CONTROLLABLE_SERVICE.DisplayName;
                        Assert.IsTrue (sc.CanShutdown, "#3");
                        sc.MachineName = "doesnotexist";
                        try {
@@ -618,7 +671,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                bool canShutdown = sc.CanShutdown;
@@ -647,7 +700,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanShutdown);
                }
 
@@ -685,7 +738,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanShutdown);
                }
 
@@ -695,7 +748,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1");
                        Assert.IsTrue (sc.CanShutdown, "#2");
                }
@@ -706,8 +759,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -743,8 +796,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -799,11 +852,11 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsTrue (sc.CanStop, "#1");
-                       sc.ServiceName = "SamSs";
+                       sc.ServiceName = UNCONTROLLABLE_SERVICE.ServiceName;
                        Assert.IsFalse (sc.CanStop, "#2");
-                       sc.DisplayName = "Workstation";
+                       sc.DisplayName = CONTROLLABLE_SERVICE.DisplayName;
                        Assert.IsTrue (sc.CanStop, "#3");
                        sc.MachineName = "doesnotexist";
                        try {
@@ -833,7 +886,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                bool canStop = sc.CanStop;
@@ -862,7 +915,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanStop);
                }
 
@@ -900,7 +953,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.IsFalse (sc1.CanStop);
                }
 
@@ -910,7 +963,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1");
                        Assert.IsTrue (sc.CanStop, "#2");
                }
@@ -921,8 +974,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -958,8 +1011,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -1014,8 +1067,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -1052,7 +1105,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                sc.Continue ();
@@ -1081,8 +1134,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
-                       ServiceController sc2 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2");
@@ -1094,7 +1147,7 @@ namespace MonoTests.System.ServiceProcess
                                // Cannot resume NetDDE service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (DISABLED_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -1145,8 +1198,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
-                       ServiceController sc2 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -1155,10 +1208,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Continue ();
                                Assert.Fail ("#B1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot resume SamSs service on computer '.'
+                               // Cannot resume service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (UNCONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -1181,8 +1234,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -1199,8 +1252,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -1219,10 +1272,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Continue ();
                                Assert.Fail ("#D1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot resume Schedule service on computer '.'
+                               // Cannot resume the service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                Assert.IsNotNull (ex.Message, "#D3");
-                               Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                               Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -1271,52 +1324,52 @@ namespace MonoTests.System.ServiceProcess
                        ServiceController [] dependentServices = null;
 
                        // single dependent service
-                       sc = new ServiceController ("dmserver", ".");
+                       sc = new ServiceController (SERVICE_WITH_ONE_DEPENDENT.ServiceName, ".");
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#A1");
                        Assert.AreEqual (1, dependentServices.Length, "#A2");
-                       Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#A3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDENT.Dependents, ServiceNames (dependentServices), "#A3");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "alerter";
+                       sc.ServiceName = SERVICE_WITH_NO_DEPENDENTS.ServiceName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#B1");
                        Assert.AreEqual (1, dependentServices.Length, "#B2");
-                       Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#B3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDENT.Dependents, ServiceNames (dependentServices), "#B3");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "Spooler";
+                       sc.DisplayName = SERVICE_WITH_MANY_DEPENDENTS.DisplayName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#C1");
                        Assert.AreEqual (1, dependentServices.Length, "#C2");
-                       Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#C3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDENT.Dependents, ServiceNames (dependentServices), "#C3");
 
                        // modifying MachineName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
                        sc.MachineName = "doesnotexist";
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#D1");
-                       Assert.AreEqual (1, dependentServices.Length, "#D2");
-                       Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#D3");
+                       Assert.AreEqual (1, dependentServices.Length, "#D");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDENT.Dependents, ServiceNames (dependentServices), "#D3");
 
                        // no dependent services
-                       sc = new ServiceController ("alerter", ".");
+                       sc = new ServiceController (SERVICE_WITH_NO_DEPENDENTS.ServiceName, ".");
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#E1");
                        Assert.AreEqual (0, dependentServices.Length, "#E2");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "dmserver";
+                       sc.ServiceName = SERVICE_WITH_MANY_DEPENDENTS.ServiceName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#F1");
                        Assert.AreEqual (0, dependentServices.Length, "#F2");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "Workstation";
+                       sc.DisplayName = SERVICE_WITH_ONE_DEPENDENT.DisplayName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#G1");
                        Assert.AreEqual (0, dependentServices.Length, "#G2");
@@ -1329,39 +1382,35 @@ namespace MonoTests.System.ServiceProcess
                        Assert.AreEqual (0, dependentServices.Length, "#H2");
 
                        // multiple dependent services
-                       sc = new ServiceController ("TapiSrv", ".");
+                       sc = new ServiceController (SERVICE_WITH_MANY_DEPENDENTS.ServiceName, ".");
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#I1");
-                       Assert.AreEqual (2, dependentServices.Length, "#I2");
-                       Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#I3");
-                       Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#I4");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents.Length, dependentServices.Length, "#I2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents, ServiceNames (dependentServices), "#I3");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "spooler";
+                       sc.ServiceName = SERVICE_WITH_NO_DEPENDENTS.ServiceName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#J1");
-                       Assert.AreEqual (2, dependentServices.Length, "#J3");
-                       Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#J4");
-                       Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#J5");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents.Length, dependentServices.Length, "#J3");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents, ServiceNames (dependentServices), "#J3");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "Alerter";
+                       sc.DisplayName = SERVICE_WITH_ONE_DEPENDENT.DisplayName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#K1");
-                       Assert.AreEqual (2, dependentServices.Length, "#K2");
-                       Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#K3");
-                       Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#K4");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents.Length, dependentServices.Length, "#K2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents, ServiceNames (dependentServices), "#K3");
 
                        // modifying MachineName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
                        sc.MachineName = Environment.MachineName;
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#L1");
-                       Assert.AreEqual (2, dependentServices.Length, "#L2");
-                       Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#L3");
-                       Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#L4");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents.Length, dependentServices.Length, "#L2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDENTS.Dependents, ServiceNames (dependentServices), "#L3");
                }
 
                [Test]
@@ -1370,7 +1419,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("dmserver",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                ServiceController [] dependenServices = sc.DependentServices;
@@ -1399,11 +1448,10 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("NetDDE", ".");
+                       ServiceController sc = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        ServiceController [] dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#1");
-                       Assert.AreEqual (1, dependentServices.Length, "#2");
-                       Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#3");
+                       Assert.AreEqual (DISABLED_SERVICE.Dependents, ServiceNames (dependentServices), "#2");
                }
 
                [Test]
@@ -1459,36 +1507,39 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
+                       var s1 = WORKSTATION_SERVICE;
+                       var s2 = WINDOWS_SEARCH_SERVICE;
+
                        ServiceController sc = new ServiceController ();
-                       sc.DisplayName = "workstation";
-                       Assert.AreEqual ("workstation", sc.DisplayName, "#A1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2");
+                       sc.DisplayName = s1.DisplayName.ToLower ();
+                       Assert.AreEqual (s1.DisplayName.ToLower (), sc.DisplayName, "#A1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#A2");
 
-                       sc.DisplayName = "alerter";
-                       Assert.AreEqual ("alerter", sc.DisplayName, "#B1");
-                       Assert.AreEqual ("Alerter", sc.ServiceName, "#B2");
+                       sc.DisplayName = s2.DisplayName.ToLower ();
+                       Assert.AreEqual (s2.DisplayName.ToLower (), sc.DisplayName, "#B1");
+                       Assert.AreEqual (s2.ServiceName, sc.ServiceName, "#B2");
 
-                       sc = new ServiceController ("workstation");
-                       sc.DisplayName = "alerter";
-                       Assert.AreEqual ("alerter", sc.DisplayName, "#C1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#C2");
-                       Assert.AreEqual ("workstation", sc.DisplayName, "#C3");
+                       sc = new ServiceController (s1.DisplayName.ToLower ());
+                       sc.DisplayName = s2.DisplayName.ToLower ();
+                       Assert.AreEqual (s2.DisplayName.ToLower (), sc.DisplayName, "#C1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#C2");
+                       Assert.AreEqual (s1.DisplayName.ToLower (), sc.DisplayName, "#C3");
 
-                       sc.DisplayName = "alerter";
-                       Assert.AreEqual ("alerter", sc.DisplayName, "#D1");
-                       Assert.AreEqual ("Alerter", sc.ServiceName, "#D2");
+                       sc.DisplayName = s2.DisplayName.ToLower ();
+                       Assert.AreEqual (s2.DisplayName.ToLower (), sc.DisplayName, "#D1");
+                       Assert.AreEqual (s2.ServiceName, sc.ServiceName, "#D2");
 
-                       sc.DisplayName = "workstation";
-                       Assert.AreEqual ("workstation", sc.DisplayName, "#E1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#E2");
+                       sc.DisplayName = s1.DisplayName;
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#E1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#E2");
 
-                       sc = new ServiceController ("workstation");
-                       Assert.AreEqual ("workstation", sc.DisplayName, "#F1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#F2");
+                       sc = new ServiceController (s1.DisplayName.ToLower ());
+                       Assert.AreEqual (s1.DisplayName.ToLower (), sc.DisplayName, "#F1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#F2");
 
-                       sc.DisplayName = "Workstation";
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#G1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2");
+                       sc.DisplayName = s1.DisplayName;
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#G1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#G2");
                }
 
                [Test]
@@ -1497,7 +1548,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("dmserver",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                string displayName = sc.DisplayName;
@@ -1526,8 +1577,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("NetDDE", ".");
-                       Assert.AreEqual ("Network DDE", sc.DisplayName);
+                       ServiceController sc = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       Assert.AreEqual (DISABLED_SERVICE.DisplayName, sc.DisplayName);
                }
 
                [Test]
@@ -1565,9 +1616,9 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.DisplayName = "workstation";
-                       Assert.AreEqual ("workstation", sc.DisplayName, "#A1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2");
+                       sc.DisplayName = WORKSTATION_SERVICE.DisplayName.ToLower ();
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName.ToLower (), sc.DisplayName, "#A1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#A2");
                }
 
                [Test]
@@ -1611,10 +1662,10 @@ namespace MonoTests.System.ServiceProcess
                        Assert.AreEqual (string.Empty, sc.DisplayName, "#A1");
                        Assert.AreEqual (string.Empty, sc.ServiceName, "#A2");
 
-                       sc.DisplayName = "WorkStation";
+                       sc.DisplayName = WORKSTATION_SERVICE.DisplayName;
 
-                       Assert.AreEqual ("WorkStation", sc.DisplayName, "#B1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#B2");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#B1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#B2");
 
                        sc.DisplayName = string.Empty;
 
@@ -1629,7 +1680,7 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.DisplayName = "Alerter";
+                       sc.DisplayName = CONTROLLABLE_SERVICE.DisplayName;
                        try {
                                sc.DisplayName = null;
                                Assert.Fail ("#1");
@@ -1640,7 +1691,7 @@ namespace MonoTests.System.ServiceProcess
                                Assert.AreEqual ("value", ex.ParamName, "#5");
                                Assert.IsNull (ex.InnerException, "#6");
                        }
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#7");
+                       Assert.AreEqual (CONTROLLABLE_SERVICE.DisplayName, sc.DisplayName, "#7");
                }
 
                [Test]
@@ -1650,10 +1701,10 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.DisplayName = "lanmanworkstation";
-                       Assert.AreEqual ("lanmanworkstation", sc.DisplayName, "#A1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#A3");
+                       sc.DisplayName = WORKSTATION_SERVICE.ServiceName;
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.DisplayName, "#A1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#A2");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#A3");
                }
 
                [Test]
@@ -1662,7 +1713,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Disk", ".");
+                       ServiceController sc = new ServiceController (DISK_DRIVER_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        try {
@@ -1670,10 +1721,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE);
                                        Assert.Fail ("#B1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#B3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#B4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                        Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -1690,10 +1741,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_DEVICEEVENT);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -1710,10 +1761,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_HARDWAREPROFILECHANGE);
                                        Assert.Fail ("#D1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                        Assert.IsNotNull (ex.Message, "#D3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#D4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#D4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                        Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -1730,10 +1781,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE);
                                        Assert.Fail ("#E1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2");
                                        Assert.IsNotNull (ex.Message, "#E3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#E4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#E4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5");
                                        Assert.IsNotNull (ex.InnerException, "#E6");
 
@@ -1750,10 +1801,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDADD);
                                        Assert.Fail ("#F1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#F2");
                                        Assert.IsNotNull (ex.Message, "#F3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#F4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#F4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#F5");
                                        Assert.IsNotNull (ex.InnerException, "#F6");
 
@@ -1770,10 +1821,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDDISABLE);
                                        Assert.Fail ("#G1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2");
                                        Assert.IsNotNull (ex.Message, "#G3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#G4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#G4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5");
                                        Assert.IsNotNull (ex.InnerException, "#G6");
 
@@ -1790,10 +1841,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDENABLE);
                                        Assert.Fail ("#H1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#H2");
                                        Assert.IsNotNull (ex.Message, "#H3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#H4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#H4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#H5");
                                        Assert.IsNotNull (ex.InnerException, "#H6");
 
@@ -1810,10 +1861,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDREMOVE);
                                        Assert.Fail ("#I1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2");
                                        Assert.IsNotNull (ex.Message, "#I3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#I4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#I4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5");
                                        Assert.IsNotNull (ex.InnerException, "#I6");
 
@@ -1830,10 +1881,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PARAMCHANGE);
                                        Assert.Fail ("#J1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#J2");
                                        Assert.IsNotNull (ex.Message, "#J3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#J4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#J4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#J5");
                                        Assert.IsNotNull (ex.InnerException, "#J6");
 
@@ -1850,10 +1901,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE);
                                        Assert.Fail ("#K1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#K2");
                                        Assert.IsNotNull (ex.Message, "#K3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#K4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#K4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#K5");
                                        Assert.IsNotNull (ex.InnerException, "#K6");
 
@@ -1870,10 +1921,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_POWEREVENT);
                                        Assert.Fail ("#L1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#L2");
                                        Assert.IsNotNull (ex.Message, "#L3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#L4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#L4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#L5");
                                        Assert.IsNotNull (ex.InnerException, "#L6");
 
@@ -1890,10 +1941,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SESSIONCHANGE);
                                        Assert.Fail ("#M1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#M2");
                                        Assert.IsNotNull (ex.Message, "#M3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#M4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#M4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#M5");
                                        Assert.IsNotNull (ex.InnerException, "#M6");
 
@@ -1910,10 +1961,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SHUTDOWN);
                                        Assert.Fail ("#N1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#N2");
                                        Assert.IsNotNull (ex.Message, "#N3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#N4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#N4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#N5");
                                        Assert.IsNotNull (ex.InnerException, "#N6");
 
@@ -1930,10 +1981,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP);
                                        Assert.Fail ("#O1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#O2");
                                        Assert.IsNotNull (ex.Message, "#O3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#O4");
+                                       Assert.IsTrue (ex.Message.IndexOf (DISK_DRIVER_SERVICE.ServiceName) != -1, "#O4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#O5");
                                        Assert.IsNotNull (ex.InnerException, "#O6");
 
@@ -1958,7 +2009,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE);
@@ -1987,7 +2038,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        try {
@@ -1995,10 +2046,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#B1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#B3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                        Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -2018,10 +2069,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (256);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2046,7 +2097,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Pause ();
@@ -2063,10 +2114,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2091,7 +2142,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        try {
@@ -2099,10 +2150,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE);
                                        Assert.Fail ("#B1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#B3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                        Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -2119,10 +2170,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_DEVICEEVENT);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2139,10 +2190,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_HARDWAREPROFILECHANGE);
                                        Assert.Fail ("#D1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                        Assert.IsNotNull (ex.Message, "#D3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                        Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -2159,10 +2210,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE);
                                        Assert.Fail ("#E1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2");
                                        Assert.IsNotNull (ex.Message, "#E3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#E4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#E4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5");
                                        Assert.IsNotNull (ex.InnerException, "#E6");
 
@@ -2179,10 +2230,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDADD);
                                        Assert.Fail ("#F1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#F2");
                                        Assert.IsNotNull (ex.Message, "#F3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#F4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#F4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#F5");
                                        Assert.IsNotNull (ex.InnerException, "#F6");
 
@@ -2199,10 +2250,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDDISABLE);
                                        Assert.Fail ("#G1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2");
                                        Assert.IsNotNull (ex.Message, "#G3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#G4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#G4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5");
                                        Assert.IsNotNull (ex.InnerException, "#G6");
 
@@ -2219,10 +2270,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDENABLE);
                                        Assert.Fail ("#H1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#H2");
                                        Assert.IsNotNull (ex.Message, "#H3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#H4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#H4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#H5");
                                        Assert.IsNotNull (ex.InnerException, "#H6");
 
@@ -2239,10 +2290,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDREMOVE);
                                        Assert.Fail ("#I1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2");
                                        Assert.IsNotNull (ex.Message, "#I3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#I4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#I4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5");
                                        Assert.IsNotNull (ex.InnerException, "#I6");
 
@@ -2259,10 +2310,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PARAMCHANGE);
                                        Assert.Fail ("#J1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#J2");
                                        Assert.IsNotNull (ex.Message, "#J3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#J4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#J4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#J5");
                                        Assert.IsNotNull (ex.InnerException, "#J6");
 
@@ -2279,10 +2330,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE);
                                        Assert.Fail ("#K1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#K2");
                                        Assert.IsNotNull (ex.Message, "#K3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#K4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#K4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#K5");
                                        Assert.IsNotNull (ex.InnerException, "#K6");
 
@@ -2299,10 +2350,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_POWEREVENT);
                                        Assert.Fail ("#L1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#L2");
                                        Assert.IsNotNull (ex.Message, "#L3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#L4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#L4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#L5");
                                        Assert.IsNotNull (ex.InnerException, "#L6");
 
@@ -2319,10 +2370,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SESSIONCHANGE);
                                        Assert.Fail ("#M1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#M2");
                                        Assert.IsNotNull (ex.Message, "#M3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#M4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#M4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#M5");
                                        Assert.IsNotNull (ex.InnerException, "#M6");
 
@@ -2339,10 +2390,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SHUTDOWN);
                                        Assert.Fail ("#N1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#N2");
                                        Assert.IsNotNull (ex.Message, "#N3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#N4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#N4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#N5");
                                        Assert.IsNotNull (ex.InnerException, "#N6");
 
@@ -2359,10 +2410,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP);
                                        Assert.Fail ("#O1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#O2");
                                        Assert.IsNotNull (ex.Message, "#O3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#O4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#O4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#O5");
                                        Assert.IsNotNull (ex.InnerException, "#O6");
 
@@ -2415,7 +2466,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Pause ();
@@ -2440,7 +2491,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Pause ();
@@ -2452,10 +2503,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#B1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#B3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                        Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -2480,7 +2531,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Stop ();
@@ -2495,10 +2546,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2515,10 +2566,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (128);
                                        Assert.Fail ("#D1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                        Assert.IsNotNull (ex.Message, "#D3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                        Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -2543,7 +2594,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Stop ();
@@ -2556,10 +2607,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2576,10 +2627,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (128);
                                        Assert.Fail ("#D1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                        Assert.IsNotNull (ex.Message, "#D3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                        Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -2604,7 +2655,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule", ".");
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A");
 
                        sc.Stop ();
@@ -2614,10 +2665,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (127);
                                        Assert.Fail ("#B1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                        Assert.IsNotNull (ex.Message, "#B3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                        Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -2634,10 +2685,10 @@ namespace MonoTests.System.ServiceProcess
                                        sc.ExecuteCommand (128);
                                        Assert.Fail ("#C1");
                                } catch (InvalidOperationException ex) {
-                                       // Cannot control Schedule service on computer '.'
+                                       // Cannot control XXX service on computer '.'
                                        Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
                                        Assert.IsNotNull (ex.Message, "#C3");
-                                       Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#C4");
                                        Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
                                        Assert.IsNotNull (ex.InnerException, "#C6");
 
@@ -2686,46 +2737,40 @@ namespace MonoTests.System.ServiceProcess
                        devices = ServiceController.GetDevices ();
                        Assert.IsNotNull (devices, "#A1");
 
-                       bool foundDisk = false;
-                       bool foundAlerter = false;
+                       bool foundKernelService = false;
+                       bool foundShareProcessService = false;
 
                        foreach (ServiceController sc in devices) {
-                               switch (sc.ServiceName) {
-                               case "Disk":
-                                       Assert.AreEqual ("Disk Driver", sc.DisplayName, "#A2");
+                               if (sc.ServiceName.ToLower () == KERNEL_SERVICE.ServiceName.ToLower ()) {
+                                       Assert.AreEqual (KERNEL_SERVICE.DisplayName, sc.DisplayName, "#A2");
                                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A3");
-                                       foundDisk = true;
-                                       break;
-                               case "Alerter":
-                                       foundAlerter = true;
-                                       break;
+                                       foundKernelService = true;
+                               } else if (sc.ServiceName.ToLower () == SHARE_PROCESS_SERVICE.ServiceName.ToLower ()) {
+                                       foundShareProcessService = true;
                                }
                        }
 
-                       Assert.IsTrue (foundDisk, "#A4");
-                       Assert.IsFalse (foundAlerter, "#A5");
+                       Assert.IsTrue (foundKernelService, "#A4");
+                       Assert.IsFalse (foundShareProcessService, "#A5");
 
                        devices = ServiceController.GetDevices (Environment.MachineName);
                        Assert.IsNotNull (devices, "#B1");
 
-                       foundDisk = false;
-                       foundAlerter = false;
+                       foundKernelService = false;
+                       foundShareProcessService = false;
 
                        foreach (ServiceController sc in devices) {
-                               switch (sc.ServiceName) {
-                               case "Disk":
-                                       Assert.AreEqual ("Disk Driver", sc.DisplayName, "#B2");
+                               if (sc.ServiceName.ToLower () == KERNEL_SERVICE.ServiceName.ToLower ()) {
+                                       Assert.AreEqual (KERNEL_SERVICE.DisplayName, sc.DisplayName, "#B2");
                                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#B3");
-                                       foundDisk = true;
-                                       break;
-                               case "Alerter":
-                                       foundAlerter = true;
-                                       break;
+                                       foundKernelService = true;
+                               } else if (sc.ServiceName.ToLower () == SHARE_PROCESS_SERVICE.ServiceName.ToLower ()) {
+                                       foundShareProcessService = true;
                                }
                        }
 
-                       Assert.IsTrue (foundDisk, "#B4");
-                       Assert.IsFalse (foundAlerter, "#B5");
+                       Assert.IsTrue (foundKernelService, "#B4");
+                       Assert.IsFalse (foundShareProcessService, "#B5");
                }
 
                [Test]
@@ -2800,44 +2845,38 @@ namespace MonoTests.System.ServiceProcess
                        services = ServiceController.GetServices ();
                        Assert.IsNotNull (services, "#A1");
 
-                       bool foundDisk = false;
-                       bool foundWorkstation = false;
+                       bool foundKernelService = false;
+                       bool foundShareProcessService = false;
 
                        foreach (ServiceController sc in services) {
-                               switch (sc.ServiceName) {
-                               case "Disk":
-                                       foundDisk = true;
-                                       break;
-                               case "lanmanworkstation":
-                                       foundWorkstation = true;
-                                       break;
+                               if (sc.ServiceName.ToLower () == KERNEL_SERVICE.ServiceName.ToLower ()) {
+                                       foundKernelService = true;
+                               } else if (sc.ServiceName.ToLower () == SHARE_PROCESS_SERVICE.ServiceName.ToLower ()) {
+                                       foundShareProcessService = true;
                                }
                        }
 
-                       Assert.IsFalse (foundDisk, "#A4");
-                       Assert.IsTrue (foundWorkstation, "#A5");
+                       Assert.IsFalse (foundKernelService, "#A4");
+                       Assert.IsTrue (foundShareProcessService, "#A5");
 
                        services = ServiceController.GetServices (Environment.MachineName);
                        Assert.IsNotNull (services, "#B1");
 
-                       foundDisk = false;
-                       foundWorkstation = false;
+                       foundKernelService = false;
+                       foundShareProcessService = false;
 
                        foreach (ServiceController sc in services) {
-                               switch (sc.ServiceName) {
-                               case "Disk":
-                                       foundDisk = true;
-                                       break;
-                               case "lanmanworkstation":
-                                       Assert.AreEqual ("Workstation", sc.DisplayName, "#B2");
+                               if (sc.ServiceName.ToLower () == KERNEL_SERVICE.ServiceName.ToLower ()) {
+                                       foundKernelService = true;
+                               } else if (sc.ServiceName.ToLower () == SHARE_PROCESS_SERVICE.ServiceName.ToLower ()) {
+                                       Assert.AreEqual (SHARE_PROCESS_SERVICE.DisplayName, sc.DisplayName, "#B2");
                                        Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#B3");
-                                       foundWorkstation = true;
-                                       break;
+                                       foundShareProcessService = true;
                                }
                        }
 
-                       Assert.IsFalse (foundDisk, "#B4");
-                       Assert.IsTrue (foundWorkstation, "#B5");
+                       Assert.IsFalse (foundKernelService, "#B4");
+                       Assert.IsTrue (foundShareProcessService, "#B5");
                }
 
                [Test]
@@ -2908,25 +2947,25 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.ServiceName = "alerter";
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#A1");
+                       sc.ServiceName = WORKSTATION_SERVICE.ServiceName;
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#A1");
                        Assert.AreEqual (".", sc.MachineName, "#A2");
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#A3");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#A3");
 
                        sc.MachineName = Environment.MachineName;
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#B1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#B1");
                        Assert.AreEqual (Environment.MachineName, sc.MachineName, "#B2");
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#B3");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#B3");
 
                        sc.MachineName = "doesnotexist";
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#C1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#C1");
                        Assert.AreEqual ("doesnotexist", sc.MachineName, "#C2");
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#C3");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#C3");
 
                        sc.MachineName = "DoesNotExist";
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#D1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#D1");
                        Assert.AreEqual ("DoesNotExist", sc.MachineName, "#D2");
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#D3");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#D3");
                }
 
                [Test]
@@ -2981,8 +3020,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3012,7 +3051,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                sc.Pause ();
@@ -3041,8 +3080,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
-                       ServiceController sc2 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2");
@@ -3054,7 +3093,7 @@ namespace MonoTests.System.ServiceProcess
                                // Cannot pause NetDDE service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (DISABLED_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -3105,8 +3144,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
-                       ServiceController sc2 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3115,10 +3154,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Pause ();
                                Assert.Fail ("#B1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot pause SamSs service on computer '.'
+                               // Cannot pause XXX service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (UNCONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -3141,8 +3180,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3177,8 +3216,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3197,10 +3236,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Pause ();
                                Assert.Fail ("#D1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot pause Schedule service on computer '.'
+                               // Cannot pause XXX service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                Assert.IsNotNull (ex.Message, "#D3");
-                               Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                               Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -3249,39 +3288,32 @@ namespace MonoTests.System.ServiceProcess
                        ServiceController [] dependentServices = null;
                        ServiceController [] servicesDependedOn = null;
 
-                       sc = new ServiceController ("NetDDE", ".");
+                       sc = new ServiceController (SERVICE_1_WITH_DEPENDENTS_AND_DEPENDED_ON.ServiceName, ".");
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#A1");
-                       Assert.AreEqual (1, dependentServices.Length, "#A2");
-                       Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#A3");
+                       Assert.AreEqual (SERVICE_1_WITH_DEPENDENTS_AND_DEPENDED_ON.Dependents, ServiceNames (dependentServices), "#A2");
                        servicesDependedOn = sc.ServicesDependedOn;
-                       Assert.IsNotNull (servicesDependedOn, "#A4");
-                       Assert.AreEqual (1, servicesDependedOn.Length, "#A5");
-                       Assert.AreEqual ("NetDDEDSDM", servicesDependedOn [0].ServiceName, "#A6");
+                       Assert.AreEqual (SERVICE_1_WITH_DEPENDENTS_AND_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#A3");
 
-                       sc.ServiceName = "rasman";
+                       sc.ServiceName = SERVICE_2_WITH_DEPENDENTS_AND_DEPENDED_ON.ServiceName;
                        sc.Refresh ();
 
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#B1");
-                       Assert.AreEqual (1, dependentServices.Length, "#B2");
-                       Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#B3");
+                       Assert.AreEqual (SERVICE_2_WITH_DEPENDENTS_AND_DEPENDED_ON.Dependents, ServiceNames (dependentServices), "#B2");
                        servicesDependedOn = sc.ServicesDependedOn;
-                       Assert.IsNotNull (servicesDependedOn, "#B4");
-                       Assert.AreEqual (1, servicesDependedOn.Length, "#B5");
-                       Assert.AreEqual ("Tapisrv", servicesDependedOn [0].ServiceName, "#B6");
+                       Assert.IsNotNull (servicesDependedOn, "#B3");
+                       Assert.AreEqual (SERVICE_2_WITH_DEPENDENTS_AND_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#A4");
 
-                       sc.DisplayName = "NetDDE";
+                       sc.DisplayName = SERVICE_3_WITH_DEPENDENTS_AND_DEPENDED_ON.ServiceName;
                        sc.Refresh ();
 
                        dependentServices = sc.DependentServices;
                        Assert.IsNotNull (dependentServices, "#C1");
-                       Assert.AreEqual (1, dependentServices.Length, "#C2");
-                       Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#C3");
+                       Assert.AreEqual (SERVICE_3_WITH_DEPENDENTS_AND_DEPENDED_ON.Dependents, ServiceNames (dependentServices), "#C2");
                        servicesDependedOn = sc.ServicesDependedOn;
-                       Assert.IsNotNull (servicesDependedOn, "#C4");
-                       Assert.AreEqual (1, servicesDependedOn.Length, "#C5");
-                       Assert.AreEqual ("NetDDEDSDM", servicesDependedOn [0].ServiceName, "#C6");
+                       Assert.IsNotNull (servicesDependedOn, "#C3");
+                       Assert.AreEqual (SERVICE_3_WITH_DEPENDENTS_AND_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#C4");
                }
 
                [Test]
@@ -3290,7 +3322,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        sc.Refresh ();
                }
@@ -3311,8 +3343,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3352,8 +3384,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3404,8 +3436,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -3450,36 +3482,40 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
+                       var s1 = WORKSTATION_SERVICE;
+                       var s2 = WINDOWS_SEARCH_SERVICE;
+
                        ServiceController sc = new ServiceController ();
-                       sc.ServiceName = "lanmanworkstation";
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#A1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2");
+                       sc.ServiceName = s1.ServiceName;
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#A1");
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#A2");
 
-                       sc.ServiceName = "alerter";
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#B1");
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#B2");
+                       sc.ServiceName = s2.ServiceName;
+                       Assert.AreEqual (s2.DisplayName, sc.DisplayName, "#B1");
+                       Assert.AreEqual (s2.ServiceName, sc.ServiceName, "#B2");
 
-                       sc = new ServiceController ("lanmanworkstation");
-                       sc.ServiceName = "alerter";
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#C1");
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#C2");
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#C3");
+                       sc = new ServiceController (s1.ServiceName);
+                       sc.ServiceName = s2.ServiceName;
+                       Assert.AreEqual (s2.ServiceName, sc.ServiceName, "#C1");
+                       Assert.AreEqual (s2.DisplayName, sc.DisplayName, "#C2");
+                       Assert.AreEqual (s2.DisplayName, sc.DisplayName, "#C3");
 
-                       sc.ServiceName = "alerter";
-                       Assert.AreEqual ("alerter", sc.ServiceName, "#D1");
-                       Assert.AreEqual ("Alerter", sc.DisplayName, "#D2");
+                       sc.ServiceName = s2.ServiceName;
+                       Assert.AreEqual (s2.ServiceName, sc.ServiceName, "#D1");
+                       Assert.AreEqual (s2.DisplayName, sc.DisplayName, "#D2");
 
-                       sc.ServiceName = "lanmanworkstation";
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#E1");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#E2");
+                       sc.ServiceName = s1.ServiceName;
+                       Assert.AreEqual (s1.ServiceName, sc.ServiceName, "#E1");
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#E2");
 
-                       sc = new ServiceController ("lanmanWorkstation");
-                       Assert.AreEqual ("lanmanWorkstation", sc.ServiceName, "#F1");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#F2");
+                       sc = new ServiceController (s1.ServiceName.ToUpper ());
+                       Assert.AreEqual (s1.ServiceName.ToUpper (), sc.ServiceName, "#F1");
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#F2");
 
-                       sc.ServiceName = "LanManWorkstation";
-                       Assert.AreEqual ("LanManWorkstation", sc.ServiceName, "#G1");
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#G2");
+                       var serviceName = s1.ServiceName [0].ToString ().ToUpper () + s1.ServiceName.Substring (1).ToLower ();
+                       sc.ServiceName = serviceName;
+                       Assert.AreEqual (serviceName, sc.ServiceName, "#G1");
+                       Assert.AreEqual (s1.DisplayName, sc.DisplayName, "#G2");
                }
 
                [Test]
@@ -3488,7 +3524,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("dmserver",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                string serviceName = sc.ServiceName;
@@ -3517,8 +3553,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("NetDDE", ".");
-                       Assert.AreEqual ("NetDDE", sc.ServiceName);
+                       ServiceController sc = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       Assert.AreEqual (DISABLED_SERVICE.ServiceName, sc.ServiceName);
                }
 
                [Test]
@@ -3556,9 +3592,9 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.ServiceName = "lanmanworkstation";
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#2");
+                       sc.ServiceName = WORKSTATION_SERVICE.ServiceName;
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#2");
                }
 
                [Test]
@@ -3601,10 +3637,10 @@ namespace MonoTests.System.ServiceProcess
                        Assert.AreEqual (string.Empty, sc.DisplayName, "#A1");
                        Assert.AreEqual (string.Empty, sc.ServiceName, "#A2");
 
-                       sc.ServiceName = "lanmanworkstation";
+                       sc.ServiceName = WORKSTATION_SERVICE.ServiceName;
 
-                       Assert.AreEqual ("Workstation", sc.DisplayName, "#B1");
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#B2");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName, sc.DisplayName, "#B1");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#B2");
 
                        try {
                                sc.ServiceName = string.Empty;
@@ -3628,7 +3664,7 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.ServiceName = "lanmanworkstation";
+                       sc.ServiceName = WORKSTATION_SERVICE.ServiceName;
                        try {
                                sc.ServiceName = null;
                                Assert.Fail ("#1");
@@ -3640,7 +3676,7 @@ namespace MonoTests.System.ServiceProcess
                                Assert.IsNull (ex.InnerException, "#6");
                        }
 
-                       Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#7");
+                       Assert.AreEqual (WORKSTATION_SERVICE.ServiceName, sc.ServiceName, "#7");
                }
 
                [Test]
@@ -3650,16 +3686,16 @@ namespace MonoTests.System.ServiceProcess
                                Assert.Ignore ("Running on Unix.");
 
                        ServiceController sc = new ServiceController ();
-                       sc.ServiceName = "workstation";
+                       sc.ServiceName = WORKSTATION_SERVICE.DisplayName.ToLower ();
                        try {
                                string displayName = sc.DisplayName;
                                Assert.Fail ("#1: " + displayName);
                        } catch (InvalidOperationException ex) {
-                               // Display name could not be retrieved for service workstation
+                               // Display name could not be retrieved for service XXX
                                // on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
                                Assert.IsNotNull (ex.Message, "#3");
-                               Assert.IsTrue (ex.Message.IndexOf ("workstation") != -1, "#4");
+                               Assert.IsTrue (ex.Message.IndexOf (WORKSTATION_SERVICE.DisplayName.ToLower ()) != -1, "#4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
                                Assert.IsNotNull (ex.InnerException, "#6");
 
@@ -3671,7 +3707,7 @@ namespace MonoTests.System.ServiceProcess
                                Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10");
                                Assert.IsNull (win32Error.InnerException, "#11");
                        }
-                       Assert.AreEqual ("workstation", sc.ServiceName, "#12");
+                       Assert.AreEqual (WORKSTATION_SERVICE.DisplayName.ToLower (), sc.ServiceName, "#12");
                }
 
                [Test]
@@ -3684,27 +3720,27 @@ namespace MonoTests.System.ServiceProcess
                        ServiceController [] servicesDependedOn = null;
 
                        // single depended service
-                       sc = new ServiceController ("spooler", ".");
+                       sc = new ServiceController (SERVICE_WITH_ONE_DEPENDED_ON.ServiceName, ".");
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#A1");
                        Assert.AreEqual (1, servicesDependedOn.Length, "#A2");
-                       Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#A3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#A3");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "lanmanworkstation";
+                       sc.ServiceName = SERVICE_WITH_NO_DEPENDED_ON.ServiceName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#B1");
                        Assert.AreEqual (1, servicesDependedOn.Length, "#B2");
-                       Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#B3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#B3");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "alerter";
+                       sc.DisplayName = SERVICE_WITH_MANY_DEPENDED_ON.DisplayName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#C1");
                        Assert.AreEqual (1, servicesDependedOn.Length, "#C2");
-                       Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#C3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#C3");
 
                        // modifying MachineName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
@@ -3712,24 +3748,24 @@ namespace MonoTests.System.ServiceProcess
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#D1");
                        Assert.AreEqual (1, servicesDependedOn.Length, "#D2");
-                       Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#D3");
+                       Assert.AreEqual (SERVICE_WITH_ONE_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#D3");
 
                        // no depended services
-                       sc = new ServiceController ("lanmanworkstation", ".");
+                       sc = new ServiceController (SERVICE_WITH_NO_DEPENDED_ON.ServiceName, ".");
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#E1");
                        Assert.AreEqual (0, servicesDependedOn.Length, "#E2");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "spooler";
+                       sc.ServiceName = SERVICE_WITH_MANY_DEPENDED_ON.ServiceName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#F1");
                        Assert.AreEqual (0, servicesDependedOn.Length, "#F2");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "Alerter";
+                       sc.DisplayName = SERVICE_WITH_ONE_DEPENDED_ON.DisplayName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#G1");
                        Assert.AreEqual (0, servicesDependedOn.Length, "#G2");
@@ -3742,47 +3778,35 @@ namespace MonoTests.System.ServiceProcess
                        Assert.AreEqual (0, servicesDependedOn.Length, "#H2");
 
                        // multiple depended services
-                       sc = new ServiceController ("dmadmin", ".");
+                       sc = new ServiceController (SERVICE_WITH_MANY_DEPENDED_ON.ServiceName, ".");
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#I1");
-                       Assert.AreEqual (3, servicesDependedOn.Length, "#I2");
-                       // do not rely on the order of the services
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#I3");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#I4");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#I5");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn.Length, servicesDependedOn.Length, "#I2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#I3");
 
                        // modifying ServiceName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.ServiceName = "spooler";
+                       sc.ServiceName = SERVICE_WITH_NO_DEPENDED_ON.ServiceName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#J1");
-                       Assert.AreEqual (3, servicesDependedOn.Length, "#J2");
-                       // do not rely on the order of the services
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#J3");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#J4");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#J5");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn.Length, servicesDependedOn.Length, "#J2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#J3");
 
                        // modifying DisplayName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
-                       sc.DisplayName = "Alerter";
+                       sc.DisplayName = SERVICE_WITH_ONE_DEPENDED_ON.DisplayName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#K1");
-                       Assert.AreEqual (3, servicesDependedOn.Length, "#K2");
-                       // do not rely on the order of the services
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#K3");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#K4");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#K5");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn.Length, servicesDependedOn.Length, "#K2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#K3");
 
                        // modifying MachineName does not cause cache to be cleared:
                        // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762
                        sc.MachineName = Environment.MachineName;
                        servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#L1");
-                       Assert.AreEqual (3, servicesDependedOn.Length, "#L2");
-                       // do not rely on the order of the services
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#L3");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#L4");
-                       Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#L5");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn.Length, servicesDependedOn.Length, "#L2");
+                       Assert.AreEqual (SERVICE_WITH_MANY_DEPENDED_ON.DependedOn, ServiceNames (servicesDependedOn), "#L3");
                }
 
                [Test]
@@ -3791,7 +3815,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("dmserver",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                ServiceController [] servicesDependedOn = sc.ServicesDependedOn;
@@ -3820,11 +3844,10 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("ClipSrv", ".");
+                       ServiceController sc = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        ServiceController [] servicesDependedOn = sc.ServicesDependedOn;
                        Assert.IsNotNull (servicesDependedOn, "#1");
-                       Assert.AreEqual (1, servicesDependedOn.Length, "#2");
-                       Assert.AreEqual ("NetDDE", servicesDependedOn [0].ServiceName, "#3");
+                       Assert.AreEqual (DISABLED_SERVICE.DependedOn, ServiceNames (servicesDependedOn), "#2");
                }
 
                [Test]
@@ -3882,11 +3905,11 @@ namespace MonoTests.System.ServiceProcess
 
                        ServiceController sc = null;
                        
-                       sc = new ServiceController ("dmserver", ".");
+                       sc = new ServiceController (SHARE_PROCESS_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#A1");
-                       sc.ServiceName = "Disk";
+                       sc.ServiceName = KERNEL_SERVICE.ServiceName;
                        Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#A2");
-                       sc.DisplayName = "Workstation";
+                       sc.DisplayName = SHARE_PROCESS_SERVICE.ServiceName;
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#A3");
                        sc.MachineName = "doesnotexist";
                        try {
@@ -3909,13 +3932,13 @@ namespace MonoTests.System.ServiceProcess
                                Assert.IsNull (win32Error.InnerException, "#A13");
                        }
 
-                       sc = new ServiceController ("Disk", ".");
+                       sc = new ServiceController (KERNEL_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#B1");
-                       sc.DisplayName = "Alerter";
+                       sc.DisplayName = SHARE_PROCESS_SERVICE.DisplayName;
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#B2");
                        sc.MachineName = Environment.MachineName;
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#B3");
-                       sc.ServiceName = "Disk";
+                       sc.ServiceName = KERNEL_SERVICE.ServiceName;
                        Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#B4");
                }
 
@@ -3925,7 +3948,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("dmserver",
+                       ServiceController sc = new ServiceController (SHARE_PROCESS_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                ServiceType serviceType = sc.ServiceType;
@@ -3954,7 +3977,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("NetDDE", ".");
+                       ServiceController sc = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType);
                }
 
@@ -3995,11 +4018,11 @@ namespace MonoTests.System.ServiceProcess
                        ServiceController sc = null;
 
                        sc = new ServiceController ();
-                       sc.DisplayName = "workstation";
+                       sc.DisplayName = SHARE_PROCESS_SERVICE.DisplayName.ToLower ();
                        Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#1");
 
                        sc = new ServiceController ();
-                       sc.DisplayName = "disk driver";
+                       sc.DisplayName = KERNEL_SERVICE.DisplayName.ToLower ();
                        Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#2");
                }
 
@@ -4023,8 +4046,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4054,7 +4077,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                sc.Stop ();
@@ -4083,8 +4106,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
-                       ServiceController sc2 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2");
@@ -4096,7 +4119,7 @@ namespace MonoTests.System.ServiceProcess
                                // Cannot stop NetDDE service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (DISABLED_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -4147,8 +4170,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
-                       ServiceController sc2 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4157,10 +4180,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Stop ();
                                Assert.Fail ("#B1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot stop SamSs service on computer '.'
+                               // Cannot stop XXX service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
                                Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf (UNCONTROLLABLE_SERVICE.ServiceName) != -1, "#B4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
                                Assert.IsNotNull (ex.InnerException, "#B6");
 
@@ -4183,8 +4206,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4224,8 +4247,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4244,10 +4267,10 @@ namespace MonoTests.System.ServiceProcess
                                sc1.Stop ();
                                Assert.Fail ("#D1");
                        } catch (InvalidOperationException ex) {
-                               // Cannot stop Schedule service on computer '.'
+                               // Cannot stop XXX service on computer '.'
                                Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
                                Assert.IsNotNull (ex.Message, "#D3");
-                               Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4");
+                               Assert.IsTrue (ex.Message.IndexOf (CONTROLLABLE_SERVICE.ServiceName) != -1, "#D4");
                                Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
                                Assert.IsNotNull (ex.InnerException, "#D6");
 
@@ -4292,8 +4315,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4338,7 +4361,7 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc = new ServiceController ("Schedule",
+                       ServiceController sc = new ServiceController (CONTROLLABLE_SERVICE.ServiceName,
                                "doesnotexist");
                        try {
                                sc.WaitForStatus (ServiceControllerStatus.Stopped,
@@ -4368,8 +4391,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("NetDDE", ".");
-                       ServiceController sc2 = new ServiceController ("NetDDE", ".");
+                       ServiceController sc1 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (DISABLED_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2");
@@ -4428,8 +4451,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("SamSs", ".");
-                       ServiceController sc2 = new ServiceController ("SamSs", ".");
+                       ServiceController sc1 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (UNCONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4480,8 +4503,8 @@ namespace MonoTests.System.ServiceProcess
                        if (RunningOnUnix)
                                Assert.Ignore ("Running on Unix.");
 
-                       ServiceController sc1 = new ServiceController ("Schedule", ".");
-                       ServiceController sc2 = new ServiceController ("Schedule", ".");
+                       ServiceController sc1 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
+                       ServiceController sc2 = new ServiceController (CONTROLLABLE_SERVICE.ServiceName, ".");
 
                        Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1");
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2");
@@ -4503,6 +4526,28 @@ namespace MonoTests.System.ServiceProcess
                        Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2");
                }
 
+               // Run this on .NET to generate ServiceInfo objects for services on the current machine
+//             [Test]
+               public static void DumpServices ()
+               {
+                       foreach (ServiceController sc in ServiceController.GetServices ()) {
+                               try {
+                                       var si = new ServiceInfo { ServiceName = sc.ServiceName, DisplayName = sc.DisplayName, ServiceType = sc.ServiceType, Dependents = ServiceNames (sc.DependentServices), DependedOn = ServiceNames (sc.ServicesDependedOn) };
+                                       var l = new List<string> ();
+                                       l.Add ($"ServiceName = \"{si.ServiceName}\"");
+                                       l.Add ($"DisplayName = \"{si.DisplayName}\"");
+                                       if (si.ServiceType != ServiceType.Win32ShareProcess)
+                                               l.Add ($"ServiceType = ServiceType.{si.ServiceType}");
+                                       if (si.Dependents.Length > 0)
+                                               l.Add ("Dependents = new [] { \"" + String.Join ("\", \"", si.Dependents) + "\" }");
+                                       if (si.DependedOn.Length > 0)
+                                               l.Add ("DependedOn = new [] { \"" + String.Join ("\", \"", si.DependedOn) + "\" }");
+                                       Console.WriteLine ("static ServiceInfo " + si.DisplayName.ToUpper ().Replace (' ', '_').Replace ('-', '_') + "_SERVICE = new ServiceInfo { " + String.Join (", ", l) + " };");
+                               } catch {
+                               }
+                       }
+               }
+
                private static void EnsureServiceIsRunning (ServiceController sc)
                {
                        sc.Refresh ();
@@ -4543,6 +4588,15 @@ namespace MonoTests.System.ServiceProcess
                        return false;
                }
 
+               private static string[] ServiceNames (ServiceController [] services)
+               {
+                       var result = new string [services.Length];
+                       for (var i = 0; i < result.Length; i++)
+                               result [i] = services [i].ServiceName.ToLower ();
+                       Array.Sort<string> (result);
+                       return result;
+               }
+
                private bool RunningOnUnix
                {
                        get {
index f32bb39e09182b6d88559c0758c6af511e14cddc..55de52a77844e4a891fafbbc60cafa9476b45199 100644 (file)
@@ -135,10 +135,16 @@ namespace System.Xml.Serialization
 
                void LookupTypeConvertor ()
                {
-                       // We only need this for System.Xml.Linq.
-                       var convertor = type.GetCustomAttribute<XmlTypeConvertorAttribute> ();
-                       if (convertor != null)
-                               typeConvertor = type.GetMethod (convertor.Method, BindingFlags.Static | BindingFlags.NonPublic);
+                       // We only need this for System.Xml.Linq
+                       var t = type;
+                       // HACK: because interpreter array handling is so bad
+                       if (t.IsArray)
+                               t = t.GetElementType ();
+
+                       var convertor = t.GetCustomAttribute<XmlTypeConvertorAttribute> ();
+                       if (convertor != null) {
+                               typeConvertor = t.GetMethod (convertor.Method, BindingFlags.Static | BindingFlags.NonPublic);
+                       }
                }
 
                internal void ConvertForAssignment (ref object value)
index 5d9e4b24f341cd6a2054bb8d1ab9aea3d18342e5..d03dea1ff01228e237db86dfc4a9a7028f2da73e 100644 (file)
@@ -737,7 +737,8 @@ namespace System.Xml.Serialization
                        Type type = listType.Type;
                        if (type.IsArray)
                        {
-                               list = EnsureArrayIndex ((Array)list, index, type.GetElementType());
+                               list = EnsureArrayIndex ((Array)list, index, type.GetElementType ());
+                               listType.ConvertForAssignment (ref value);
                                ((Array)list).SetValue (value, index);
                        }
                        else    // Must be IEnumerable
index 24c8f106523b44cf958527f49371d9414ba3d042..61835e709a09541daa56c89b501efc256c0ba3c1 100644 (file)
@@ -161,14 +161,12 @@ namespace MonoTests.System.XmlSerialization
                }
 
                // test constructors
-#if USE_VERSION_1_1    // It doesn't pass on MS.NET 1.1.
                [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
                public void TestConstructor()
                {
                        XmlSerializer ser = new XmlSerializer (null, "");
                }
-#else
-#endif
 
                // test basic types ////////////////////////////////////////////////////////
                [Test]
index 5415ff8e50a4beb760cc5825406fd6e49e7a3989..f93bbabc3d88e21bca92fc48e741c150f261a945 100644 (file)
@@ -2099,6 +2099,27 @@ namespace MonoTests.System.Xml.Linq
                        Assert.AreEqual (xe.Content.ToString (), "<Data />", "#3");
                }
 
+               [XmlType ("Root")]
+               public class DeserializeXElementArray_Data
+               {
+                       [XmlAnyElement]
+                       public XElement[] Content;
+               }
+
+               [Test]
+               public void DeserializeXElementArray ()
+               {
+                       var xmlString = "<Root><Data /></Root>";
+
+                       var serializer = new XmlSerializer (typeof (DeserializeXElementArray_Data));
+                       var res = serializer.Deserialize (new StringReader (xmlString));
+
+                       Assert.IsNotNull (res, "#1");
+                       Assert.AreEqual (typeof (DeserializeXElementArray_Data), res.GetType (), "#2");
+                       var xe = (DeserializeXElementArray_Data)res;
+                       Assert.AreEqual (xe.Content [0].ToString (), "<Data />", "#3");
+               }
+
                [Test] // Bug #20151
                public void XElementFromArrayWithNullValuesAsObject ()
                {
index 455d60b0d22802e0a7fba89a3671ec0977ca516b..74f1990f516f3ffd90536cfd6e6e85792e949b7d 100644 (file)
@@ -469,16 +469,6 @@ namespace System.Diagnostics
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern static IntPtr GetProcess_internal(int pid);
 
-               public static Process GetProcessById(int processId)
-               {
-                       IntPtr proc = GetProcess_internal(processId);
-                       
-                       if (proc == IntPtr.Zero)
-                               throw new ArgumentException ("Can't find process with ID " + processId.ToString ());
-
-                       return (new Process (new SafeProcessHandle (proc, false), processId));
-               }
-
                [MonoTODO ("There is no support for retrieving process information from a remote machine")]
                public static Process GetProcessById(int processId, string machineName) {
                        if (machineName == null)
@@ -487,34 +477,17 @@ namespace System.Diagnostics
                        if (!IsLocalMachine (machineName))
                                throw new NotImplementedException ();
 
-                       return GetProcessById (processId);
+                       IntPtr proc = GetProcess_internal(processId);
+
+                       if (proc == IntPtr.Zero)
+                               throw new ArgumentException ("Can't find process with ID " + processId.ToString ());
+
+                       return (new Process (new SafeProcessHandle (proc, false), processId));
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern static int[] GetProcesses_internal();
 
-               public static Process[] GetProcesses ()
-               {
-                       int [] pids = GetProcesses_internal ();
-                       if (pids == null)
-                               return new Process [0];
-
-                       var proclist = new List<Process> (pids.Length);
-                       for (int i = 0; i < pids.Length; i++) {
-                               try {
-                                       proclist.Add (GetProcessById (pids [i]));
-                               } catch (SystemException) {
-                                       /* The process might exit
-                                        * between
-                                        * GetProcesses_internal and
-                                        * GetProcessById
-                                        */
-                               }
-                       }
-
-                       return proclist.ToArray ();
-               }
-
                [MonoTODO ("There is no support for retrieving process information from a remote machine")]
                public static Process[] GetProcesses(string machineName) {
                        if (machineName == null)
@@ -523,21 +496,14 @@ namespace System.Diagnostics
                        if (!IsLocalMachine (machineName))
                                throw new NotImplementedException ();
 
-                       return GetProcesses ();
-               }
-
-               public static Process[] GetProcessesByName(string processName)
-               {
                        int [] pids = GetProcesses_internal ();
                        if (pids == null)
                                return new Process [0];
-                       
+
                        var proclist = new List<Process> (pids.Length);
                        for (int i = 0; i < pids.Length; i++) {
                                try {
-                                       Process p = GetProcessById (pids [i]);
-                                       if (String.Compare (processName, p.ProcessName, true) == 0)
-                                               proclist.Add (p);
+                                       proclist.Add (GetProcessById (pids [i]));
                                } catch (SystemException) {
                                        /* The process might exit
                                         * between
@@ -550,11 +516,6 @@ namespace System.Diagnostics
                        return proclist.ToArray ();
                }
 
-               [MonoTODO]
-               public static Process[] GetProcessesByName(string processName, string machineName) {
-                       throw new NotImplementedException();
-               }
-
                private static bool IsLocalMachine (string machineName)
                {
                        if (machineName == "." || machineName.Length == 0)
index 7b64967345f6f9090b77306735af467b3443e122..76941fc7ce3078117839ed7a13778dc9af1c676f 100644 (file)
@@ -78,6 +78,16 @@ namespace System.Net.Sockets
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
                }
 
+               public void AllowNatTraversal (bool allowed)
+               {
+                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
+               }
+
+               public static TcpListener Create (int port)
+               {
+                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
+               }
+
                ~TcpListener ()
                {
                }
index 953350146d25ed24d79e37f4a9fcd510174c4353..7a5e2dd740c87d6fc28d2de886e685c3ae156d62 100644 (file)
@@ -204,6 +204,11 @@ namespace System.Net.Sockets
                        set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                }
 
+               public void AllowNatTraversal (bool allowed)
+               {
+                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
+               }
+
                public void Dispose ()
                {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
index bffdfbc7011f2d24dfd17d0a671e48101d8e9154..88ae1d361e3f2585816a34c174e8d4c1ed579b90 100644 (file)
@@ -26,6 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Security.Authentication.ExtendedProtection;
 using System.Threading.Tasks;
 
 namespace System.Net {
@@ -33,6 +34,8 @@ namespace System.Net {
        {
                internal const string EXCEPTION_MESSAGE = "System.Net.HttpListener is not supported on the current platform.";
 
+               public delegate ExtendedProtectionPolicy ExtendedProtectionSelector (HttpListenerRequest request);
+
                public HttpListener ()
                {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
@@ -75,6 +78,27 @@ namespace System.Net {
                        set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                }
 
+               public HttpListenerTimeoutManager TimeoutManager {
+                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+               }
+
+               public ExtendedProtectionPolicy ExtendedProtectionPolicy
+               {
+                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+                       set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+               }
+
+               public ExtendedProtectionSelector ExtendedProtectionSelectorDelegate
+               {
+                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+                       set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+               }
+
+               public ServiceNameCollection DefaultServiceNames
+               {
+                       get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
+               }
+
                public void Abort ()
                {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
index 4c729de26c4ca7173a4a2b4ea9bc4c667e50d5cc..275d6d4ad14d7df3d47eb3d56b86d5f84d170dbc 100644 (file)
@@ -55,6 +55,11 @@ namespace System.Net {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
                }
 
+               public Task<HttpListenerWebSocketContext> AcceptWebSocketAsync (string subProtocol, TimeSpan keepAliveInterval)
+               {
+                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
+               }
+
                public Task<HttpListenerWebSocketContext> AcceptWebSocketAsync (string subProtocol, int receiveBufferSize, TimeSpan keepAliveInterval)
                {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
index 3977c7bad9c96a0bad0ae81c01931ac9a2ab4e6d..590c82b0bd29ccee9c1565559de387307a0c43bc 100644 (file)
@@ -67,12 +67,12 @@ namespace System.Net
                        get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                }
 
-               public bool AllowAutoRedirect {
+               public virtual bool AllowAutoRedirect {
                        get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                        set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                }
 
-               public bool AllowWriteStreamBuffering {
+               public virtual bool AllowWriteStreamBuffering {
                        get { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                        set { throw new PlatformNotSupportedException (EXCEPTION_MESSAGE); }
                }
@@ -360,6 +360,11 @@ namespace System.Net
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
                }
 
+               public System.IO.Stream GetRequestStream (out TransportContext context)
+               {
+                       throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
+               }
+
                public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
                {
                        throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
index 9c71b5409c4d28b8ddc9d485d990ebb7c2905487..1516216ddc202f9758f32eb7f794620576b18332 100644 (file)
@@ -75,6 +75,13 @@ namespace System.Runtime.InteropServices
                        return false;
                }
 
+               [MonoTODO]
+               public static void CleanupUnusedObjectsInCurrentContext ()
+               {
+                       if (Environment.IsRunningOnWindows)
+                               throw new PlatformNotSupportedException ();
+               }
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr AllocCoTaskMem (int cb);
                
index 24ada26034cf6194c17cda5df7c382b5f89942a7..4bce5168e7dea5288ecff37ad405bab3e929c66b 100644 (file)
@@ -94,6 +94,7 @@ namespace System.Threading {
                private int priority = (int) ThreadPriority.Normal;
                private IntPtr owned_mutex;
                private IntPtr suspended_event;
+               private int self_suspended;
                /* 
                 * These fields are used to avoid having to increment corlib versions
                 * when a new field is added to the unmanaged MonoThread structure.
index 91e76352ddc10f302f34f9cb9cd50091838fe9f0..c8b87782310327f36d1ffe0fbca382f0431c1987 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 162;
+               private const int mono_corlib_version = 163;
 #pragma warning restore 169
 
                [ComVisible (true)]
index 1bae2cf63bf817810294f9c3df7bdad70719e510..7c5307fa15513fe46d8c285a36e66b61d73225d7 100644 (file)
@@ -1618,6 +1618,7 @@ namespace System.Diagnostics {
             
             return new Process(machineName, ProcessManager.IsRemoteMachine(machineName), processId, null);
         }
+#endif
 
         /// <devdoc>
         ///    <para>
@@ -1683,6 +1684,7 @@ namespace System.Diagnostics {
             return GetProcesses(".");
         }
 
+#if !MONO
         /// <devdoc>
         ///    <para>
         ///       Creates a new <see cref='System.Diagnostics.Process'/>
index f01e8c0a2b3980584a0071616a35535ed35d0e6f..5c67546911beb6f1ecfd4f20ce048ed4c69ca3b1 100644 (file)
@@ -31,6 +31,7 @@ THE SOFTWARE.
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <time.h>
 #include <errno.h>
index dae93fe23a49718c0980ed4707937be3bf8160f2..934ed07b7293d62a3d769ac4e3146079a50aeb79 100644 (file)
@@ -11,7 +11,6 @@ AM_CPPFLAGS = \
 libwapiincludedir = $(includedir)/mono-$(API_VER)/mono/io-layer
 
 OTHER_H = \
-       context.h       \
        error.h         \
        io.h            \
        io-trace.h      \
@@ -31,8 +30,6 @@ OTHER_H = \
        wapi-remap.h
 
 OTHER_SRC = \
-       context.c               \
-       context.h               \
        error.c                 \
        error.h                 \
        io.c                    \
diff --git a/mono/io-layer/context.c b/mono/io-layer/context.c
deleted file mode 100644 (file)
index 75155a4..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * context.c:  Processor-specific register contexts
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-
-#include "mono/io-layer/wapi.h"
-
-gboolean GetThreadContext(gpointer handle G_GNUC_UNUSED, WapiContext *context G_GNUC_UNUSED)
-{
-       return(FALSE);
-}
-
-
-
diff --git a/mono/io-layer/context.h b/mono/io-layer/context.h
deleted file mode 100644 (file)
index 2d0e814..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * context.h:  Processor-specific register contexts
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_CONTEXT_H_
-#define _WAPI_CONTEXT_H_
-
-#include <glib.h>
-
-#include "mono/io-layer/wapi.h"
-
-/* This part is x86-specific.  MSDN states that CONTEXT is defined
- * also for MIPS, Alpha and PPC processors.
- */
-
-#define SIZE_OF_80387_REGISTERS 80
-
-#define CONTEXT_i386 0x00010000
-#define CONTEXT_i486 0x00010000
-
-#define CONTEXT_CONTROL                        (CONTEXT_i386 | 0x00000001L)
-#define CONTEXT_INTEGER                        (CONTEXT_i386 | 0x00000002L)
-#define CONTEXT_SEGMENTS               (CONTEXT_i386 | 0x00000004L)
-#define CONTEXT_FLOATING_POINT         (CONTEXT_i386 | 0x00000008L)
-#define CONTEXT_DEBUG_REGISTERS                (CONTEXT_i386 | 0x00000010L)
-#define CONTEXT_EXTENDED_REGISTERS     (CONTEXT_i386 | 0x00000020L)
-
-#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
-
-#define MAXIMUM_SUPPORTED_EXTENSION 512
-
-typedef struct 
-{
-       guint32 ControlWord;
-       guint32 StatusWord;
-       guint32 TagWord;
-       guint32 ErrorOffset;
-       guint32 ErrorSelector;
-       guint32 DataOffset;
-       guint32 DataSelector;
-       guint8 RegisterArea[SIZE_OF_80387_REGISTERS];
-       guint32 Cr0NpxState;
-} WapiFloatingSaveArea;
-
-typedef struct 
-{
-       guint32 ContextFlags;
-       guint32 Dr0;
-       guint32 Dr1;
-       guint32 Dr2;
-       guint32 Dr3;
-       guint32 Dr6;
-       guint32 Dr7;
-       
-       WapiFloatingSaveArea FloatSave;
-       
-       guint32 SegGs;
-       guint32 SegFs;
-       guint32 SegEs;
-       guint32 SegDs;
-       
-       guint32 Edi;
-       guint32 Esi;
-       guint32 Ebx;
-       guint32 Edx;
-       guint32 Ecx;
-       guint32 Eax;
-       
-       guint32 Ebp;
-       guint32 Eip;
-       guint32 SegCs;
-       guint32 EFlags;
-       guint32 Esp;
-       guint32 SegSs;
-       
-       guint8 ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
-} WapiContext;
-
-G_BEGIN_DECLS
-
-extern gboolean GetThreadContext(gpointer handle, WapiContext *context);
-
-G_END_DECLS
-
-#endif /* _WAPI_COMPEX_H_ */
index 09fea6b71393162064bcf93ccbe450cdc5246fae..ff5a53c21bdeda2c285f75e1796d9b4ffdb4fab2 100644 (file)
@@ -62,10 +62,6 @@ typedef WapiLargeInteger LARGE_INTEGER;
 typedef WapiLargeInteger *PLARGE_INTEGER;
 typedef WapiULargeInteger ULARGE_INTEGER;
 typedef WapiULargeInteger *PULARGE_INTEGER;
-typedef WapiFloatingSaveArea FLOATING_SAVE_AREA;
-typedef WapiFloatingSaveArea *PFLOATING_SAVE_AREA;
-typedef WapiContext CONTEXT;
-typedef WapiContext *PCONTEXT;
 typedef WapiFindData WIN32_FIND_DATA;
 typedef WapiFindData *LPWIN32_FIND_DATA;
 typedef WapiFileAttributesData WIN32_FILE_ATTRIBUTE_DATA;
index 783a9f1c4d4e72b1bb1eedd0d183169eefa699d0..b19465c7c68e0a12ca403bf774ff8019513e2649 100644 (file)
@@ -15,7 +15,6 @@
 #define GetLastError wapi_GetLastError
 #define SetLastError wapi_SetLastError
 #define TransmitFile wapi_TransmitFile
-#define GetThreadContext wapi_GetThreadContext
 #define CloseHandle wapi_CloseHandle 
 #define DuplicateHandle wapi_DuplicateHandle 
 #define CreateFile wapi_CreateFile
index 1af86f7712cc71cc9f4bd4dadba60027a8763b65..520bb2f7ac673d699b71b886f518492407c98036 100644 (file)
 #ifndef _WAPI_WAPI_H_
 #define _WAPI_WAPI_H_
 
+#include <sys/types.h>
+
 #include <mono/io-layer/wapi-remap.h>
 #include <mono/io-layer/types.h>
 #include <mono/io-layer/macros.h>
 #include <mono/io-layer/io.h>
-#include <mono/io-layer/context.h>
 #include <mono/io-layer/error.h>
 #include <mono/io-layer/messages.h>
 #include <mono/io-layer/security.h>
index db45a76a95e44a0c7d18d70dcbfc9dec1dc8d5cc..e18c3febebd07edd09e3849f6e6e77856ca4315a 100644 (file)
@@ -84,7 +84,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 162
+#define MONO_CORLIB_VERSION 163
 
 typedef struct
 {
index fe793ddce7fa1042f2124bf890318188752bf200..53e67682d53604ac205868943fada78ad4fc51b2 100644 (file)
@@ -138,3 +138,87 @@ mono_class_set_first_field_idx (MonoClass *klass, guint32 idx)
 
        ((MonoClassDef*)klass)->first_field_idx = idx;
 }
+
+guint32
+mono_class_get_method_count (MonoClass *klass)
+{
+       switch (klass->class_kind) {
+       case MONO_CLASS_DEF:
+       case MONO_CLASS_GTD:
+               return ((MonoClassDef*)klass)->method_count;
+       case MONO_CLASS_GINST:
+               return mono_class_get_method_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
+       case MONO_CLASS_GPARAM:
+               return 0;
+       case MONO_CLASS_ARRAY:
+               return ((MonoClassArray*)klass)->method_count;
+       case MONO_CLASS_POINTER:
+               return 0;
+       default:
+               g_assert_not_reached ();
+               return 0;
+       }
+}
+
+void
+mono_class_set_method_count (MonoClass *klass, guint32 count)
+{
+       switch (klass->class_kind) {
+       case MONO_CLASS_DEF:
+       case MONO_CLASS_GTD:
+               ((MonoClassDef*)klass)->method_count = count;
+               break;
+       case MONO_CLASS_GINST:
+               break;
+       case MONO_CLASS_GPARAM:
+       case MONO_CLASS_POINTER:
+               g_assert (count == 0);
+               break;
+       case MONO_CLASS_ARRAY:
+               ((MonoClassArray*)klass)->method_count = count;
+               break;
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+}
+
+guint32
+mono_class_get_field_count (MonoClass *klass)
+{
+       switch (klass->class_kind) {
+       case MONO_CLASS_DEF:
+       case MONO_CLASS_GTD:
+               return ((MonoClassDef*)klass)->field_count;
+       case MONO_CLASS_GINST:
+               return mono_class_get_field_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
+       case MONO_CLASS_GPARAM:
+       case MONO_CLASS_ARRAY:
+       case MONO_CLASS_POINTER:
+               return 0;
+       default:
+               g_assert_not_reached ();
+               return 0;
+       }
+}
+
+void
+mono_class_set_field_count (MonoClass *klass, guint32 count)
+{
+       switch (klass->class_kind) {
+       case MONO_CLASS_DEF:
+       case MONO_CLASS_GTD:
+               ((MonoClassDef*)klass)->field_count = count;
+               break;
+       case MONO_CLASS_GINST:
+               break;
+       case MONO_CLASS_GPARAM:
+       case MONO_CLASS_ARRAY:
+       case MONO_CLASS_POINTER:
+               g_assert (count == 0);
+               break;
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+}
index 0c14ec3b04236557fbc37d94da1ab3f042768355..afbae43bff65bd721ac8c95acd74a26aa17808c0 100644 (file)
@@ -362,24 +362,6 @@ struct _MonoClass {
                int generic_param_token; /* for generic param types, both var and mvar */
        } sizes;
 
-       /*
-        * From the TypeDef table
-        */
-       struct {
-#if MONO_SMALL_CONFIG
-               guint16 count;
-#else
-               guint32 count;
-#endif
-       } field;
-       struct {
-#if MONO_SMALL_CONFIG
-               guint16 count;
-#else
-               guint32 count;
-#endif
-       } method;
-
        /* A GC handle pointing to the corresponding type builder/generic param builder */
        guint32 ref_info_handle;
 
@@ -416,6 +398,7 @@ typedef struct {
         */
        guint32 first_method_idx;
        guint32 first_field_idx;
+       guint32 method_count, field_count;
        /* next element in the class_cache hash list (in MonoImage) */
        MonoClass *next_class_cache;
 } MonoClassDef;
@@ -436,6 +419,7 @@ typedef struct {
 
 typedef struct {
        MonoClass class;
+       guint32 method_count;
 } MonoClassArray;
 
 typedef struct {
@@ -1498,6 +1482,18 @@ mono_class_get_first_field_idx (MonoClass *klass);
 void
 mono_class_set_first_field_idx (MonoClass *klass, guint32 idx);
 
+guint32
+mono_class_get_method_count (MonoClass *klass);
+
+void
+mono_class_set_method_count (MonoClass *klass, guint32 count);
+
+guint32
+mono_class_get_field_count (MonoClass *klass);
+
+void
+mono_class_set_field_count (MonoClass *klass, guint32 count);
+
 /*Now that everything has been defined, let's include the inline functions */
 #include <mono/metadata/class-inlines.h>
 
index 042c869adccf3ee198a8e02451ca412ce496b3db..f4646c71123615982cf7aa098a864b102d9c997a 100644 (file)
@@ -1280,7 +1280,7 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error)
 {
        MonoGenericContainer *container = NULL;
        MonoImage *m = klass->image;
-       const int top = klass->field.count;
+       const int top = mono_class_get_field_count (klass);
        int i, first_field_idx;
 
        g_assert (klass->enumtype);
@@ -1444,11 +1444,11 @@ mono_class_setup_basic_field_info (MonoClass *klass)
                mono_class_setup_basic_field_info (gtd);
 
                mono_loader_lock ();
-               klass->field.count = gtd->field.count;
+               mono_class_set_field_count (klass, mono_class_get_field_count (gtd));
                mono_loader_unlock ();
        }
 
-       top = klass->field.count;
+       top = mono_class_get_field_count (klass);
 
        fields = (MonoClassField *)mono_class_alloc0 (klass, sizeof (MonoClassField) * top);
 
@@ -1550,7 +1550,7 @@ mono_class_setup_fields (MonoClass *klass)
        }
 
        mono_class_setup_basic_field_info (klass);
-       top = klass->field.count;
+       top = mono_class_get_field_count (klass);
 
        if (gtd) {
                mono_class_setup_fields (gtd);
@@ -1752,7 +1752,7 @@ void
 mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_size, gboolean sre)
 {
        int i;
-       const int top = klass->field.count;
+       const int top = mono_class_get_field_count (klass);
        guint32 layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK;
        guint32 pass, passes, real_size;
        gboolean gc_aware_layout = FALSE;
@@ -2234,7 +2234,7 @@ mono_class_setup_methods (MonoClass *klass)
                        return;
 
                /* The + 1 makes this always non-NULL to pass the check in mono_class_setup_methods () */
-               count = gklass->method.count;
+               count = mono_class_get_method_count (gklass);
                methods = (MonoMethod **)mono_class_alloc0 (klass, sizeof (MonoMethod*) * (count + 1));
 
                for (i = 0; i < count; i++) {
@@ -2264,7 +2264,7 @@ mono_class_setup_methods (MonoClass *klass)
 
                if (klass->rank == 1 && klass->element_class->rank) {
                        jagged_ctor = TRUE;
-                       klass->method.count ++;
+                       count ++;
                }
 
                if (klass->interface_count) {
@@ -2343,7 +2343,7 @@ mono_class_setup_methods (MonoClass *klass)
                MonoError error;
                int first_idx = mono_class_get_first_method_idx (klass);
 
-               count = klass->method.count;
+               count = mono_class_get_method_count (klass);
                methods = (MonoMethod **)mono_class_alloc (klass, sizeof (MonoMethod*) * count);
                for (i = 0; i < count; ++i) {
                        int idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, first_idx + i + 1);
@@ -2370,7 +2370,7 @@ mono_class_setup_methods (MonoClass *klass)
        mono_image_lock (klass->image);
 
        if (!klass->methods) {
-               klass->method.count = count;
+               mono_class_set_method_count (klass, count);
 
                /* Needed because of the double-checking locking pattern */
                mono_memory_barrier ();
@@ -2415,7 +2415,7 @@ mono_class_get_method_by_index (MonoClass *klass, int index)
                mono_class_setup_methods (klass);
                if (mono_class_has_failure (klass)) /*FIXME do proper error handling*/
                        return NULL;
-               g_assert (index >= 0 && index < klass->method.count);
+               g_assert (index >= 0 && index < mono_class_get_method_count (klass));
                return klass->methods [index];
        }
 }      
@@ -2430,14 +2430,15 @@ MonoMethod*
 mono_class_get_inflated_method (MonoClass *klass, MonoMethod *method)
 {
        MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
-       int i;
+       int i, mcount;
 
        g_assert (method->klass == gklass);
 
        mono_class_setup_methods (gklass);
        g_assert (!mono_class_has_failure (gklass)); /*FIXME do proper error handling*/
 
-       for (i = 0; i < gklass->method.count; ++i) {
+       mcount = mono_class_get_method_count (gklass);
+       for (i = 0; i < mcount; ++i) {
                if (gklass->methods [i] == method) {
                        if (klass->methods) {
                                return klass->methods [i];
@@ -2996,7 +2997,7 @@ print_implemented_interfaces (MonoClass *klass) {
                printf ("  [%03d][UUID %03d][SLOT %03d][SIZE  %03d] interface %s.%s\n", i,
                                klass->interfaces_packed [i]->interface_id,
                                klass->interface_offsets_packed [i],
-                               klass->interfaces_packed [i]->method.count,
+                               mono_class_get_method_count (klass->interfaces_packed [i]),
                                klass->interfaces_packed [i]->name_space,
                                klass->interfaces_packed [i]->name );
        printf ("Interface flags: ");
@@ -3035,7 +3036,7 @@ print_implemented_interfaces (MonoClass *klass) {
                                printf ("  [%03d][UUID %03d][SLOT %03d][SIZE  %03d] interface %s.%s\n", i,
                                                ic->interface_id,
                                                mono_class_interface_offset (klass, ic),
-                                               ic->method.count,
+                                               mono_class_get_method_count (ic),
                                                ic->name_space,
                                                ic->name );
                        }
@@ -3331,7 +3332,7 @@ find_array_interface (MonoClass *klass, const char *name)
 static int
 count_virtual_methods (MonoClass *klass)
 {
-       int i, count = 0;
+       int i, mcount, vcount = 0;
        guint32 flags;
        klass = mono_class_get_generic_type_definition (klass); /*We can find this information by looking at the GTD*/
 
@@ -3340,21 +3341,23 @@ count_virtual_methods (MonoClass *klass)
                if (mono_class_has_failure (klass))
                        return -1;
 
-               for (i = 0; i < klass->method.count; ++i) {
+               mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        flags = klass->methods [i]->flags;
                        if (flags & METHOD_ATTRIBUTE_VIRTUAL)
-                               ++count;
+                               ++vcount;
                }
        } else {
                int first_idx = mono_class_get_first_method_idx (klass);
-               for (i = 0; i < klass->method.count; ++i) {
+               mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        flags = mono_metadata_decode_table_row_col (klass->image, MONO_TABLE_METHOD, first_idx + i, MONO_METHOD_FLAGS);
 
                        if (flags & METHOD_ATTRIBUTE_VIRTUAL)
-                               ++count;
+                               ++vcount;
                }
        }
-       return count;
+       return vcount;
 }
 
 static int
@@ -3555,6 +3558,7 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite)
        ifaces_array = g_new0 (GPtrArray *, klass->idepth);
        for (j = 0; j < klass->idepth; j++) {
                k = klass->supertypes [j];
+               g_assert (k);
                num_ifaces += k->interface_count;
                for (i = 0; i < k->interface_count; i++) {
                        ic = k->interfaces [i];
@@ -4213,7 +4217,7 @@ mono_method_try_get_vtable_index (MonoMethod *method)
 static void
 mono_class_verify_vtable (MonoClass *klass)
 {
-       int i;
+       int i, count;
        char *full_name = mono_type_full_name (&klass->byval_arg);
 
        printf ("*** Verifying VTable of class '%s' \n", full_name);
@@ -4223,7 +4227,8 @@ mono_class_verify_vtable (MonoClass *klass)
        if (!klass->methods)
                return;
 
-       for (i = 0; i < klass->method.count; ++i) {
+       count = mono_class_method_count (klass);
+       for (i = 0; i < count; ++i) {
                MonoMethod *cm = klass->methods [i];
                int slot;
 
@@ -4253,8 +4258,9 @@ mono_class_verify_vtable (MonoClass *klass)
 #endif
 
 static void
-print_unimplemented_interface_method_info (MonoClass *klass, MonoClass *ic, MonoMethod *im, int im_slot, MonoMethod **overrides, int onum) {
-       int index;
+print_unimplemented_interface_method_info (MonoClass *klass, MonoClass *ic, MonoMethod *im, int im_slot, MonoMethod **overrides, int onum)
+{
+       int index, mcount;
        char *method_signature;
        char *type_name;
        
@@ -4275,7 +4281,8 @@ print_unimplemented_interface_method_info (MonoClass *klass, MonoClass *ic, Mono
                g_free (name);
                return;
        }
-       for (index = 0; index < klass->method.count; ++index) {
+       mcount = mono_class_get_method_count (klass);
+       for (index = 0; index < mcount; ++index) {
                MonoMethod *cm = klass->methods [index];
                method_signature = mono_signature_get_desc (mono_method_signature (cm), TRUE);
 
@@ -4384,7 +4391,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
        } else if (ifaces) {
                for (i = 0; i < ifaces->len; i++) {
                        MonoClass *ic = (MonoClass *)g_ptr_array_index (ifaces, i);
-                       max_vtsize += ic->method.count;
+                       max_vtsize += mono_class_get_method_count (ic);
                }
                g_ptr_array_free (ifaces, TRUE);
                ifaces = NULL;
@@ -4401,7 +4408,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                cur_slot = klass->parent->vtable_size;
        }
 
-       max_vtsize += klass->method.count;
+       max_vtsize += mono_class_get_method_count (klass);
 
        /*Array have a slot for stelemref*/
        if (mono_class_need_stelemref_method (klass)) {
@@ -4450,7 +4457,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
 
                /* Have to set method->slot for abstract virtual methods */
                if (klass->methods && gklass->methods) {
-                       for (i = 0; i < klass->method.count; ++i)
+                       int mcount = mono_class_get_method_count (klass);
+                       for (i = 0; i < mcount; ++i)
                                if (klass->methods [i]->slot == -1)
                                        klass->methods [i]->slot = gklass->methods [i]->slot;
                }
@@ -4481,7 +4489,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                                
                                mono_class_setup_methods (parent_interface); /*FIXME Just kill this whole chunk of dead code*/
                                TRACE_INTERFACE_VTABLE (printf ("    +++ Inheriting interface %s.%s\n", parent_interface->name_space, parent_interface->name));
-                               for (j = 0; j < parent_interface->method.count && !mono_class_has_failure (klass); j++) {
+                               int mcount = mono_class_get_method_count (parent_interface);
+                               for (j = 0; j < mcount && !mono_class_has_failure (klass); j++) {
                                        vtable [interface_offset + j] = parent->vtable [parent_interface_offset + j];
                                        TRACE_INTERFACE_VTABLE (printf ("    --- Inheriting: [%03d][(%03d)+(%03d)] => [%03d][(%03d)+(%03d)]\n",
                                                        parent_interface_offset + j, parent_interface_offset, j,
@@ -4576,7 +4585,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                }
                
                // Loop on all interface methods...
-               for (im_index = 0; im_index < ic->method.count; im_index++) {
+               int mcount = mono_class_get_method_count (ic);
+               for (im_index = 0; im_index < mcount; im_index++) {
                        MonoMethod *im = ic->methods [im_index];
                        int im_slot = ic_offset + im->slot;
                        MonoMethod *override_im = (override_map != NULL) ? (MonoMethod *)g_hash_table_lookup (override_map, im) : NULL;
@@ -4650,7 +4660,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
                        ic = klass->interfaces_packed [i];
                        ic_offset = mono_class_interface_offset (klass, ic);
                        
-                       for (im_index = 0; im_index < ic->method.count; im_index++) {
+                       int mcount = mono_class_get_method_count (ic);
+                       for (im_index = 0; im_index < mcount; im_index++) {
                                MonoMethod *im = ic->methods [im_index];
                                int im_slot = ic_offset + im->slot;
                                
@@ -4901,7 +4912,7 @@ mono_method_get_vtable_slot (MonoMethod *method)
                        return -1;
                if (method->slot == -1) {
                        MonoClass *gklass;
-                       int i;
+                       int i, mcount;
 
                        if (!mono_class_is_ginst (method->klass)) {
                                g_assert (method->is_inflated);
@@ -4913,11 +4924,12 @@ mono_method_get_vtable_slot (MonoMethod *method)
                        gklass = mono_class_get_generic_class (method->klass)->container_class;
                        mono_class_setup_methods (method->klass);
                        g_assert (method->klass->methods);
-                       for (i = 0; i < method->klass->method.count; ++i) {
+                       mcount = mono_class_get_method_count (method->klass);
+                       for (i = 0; i < mcount; ++i) {
                                if (method->klass->methods [i] == method)
                                        break;
                        }
-                       g_assert (i < method->klass->method.count);
+                       g_assert (i < mcount);
                        g_assert (gklass->methods);
                        method->slot = gklass->methods [i]->slot;
                }
@@ -4988,13 +5000,14 @@ static GenericArrayMethodInfo *generic_array_method_info = NULL;
 static int
 generic_array_methods (MonoClass *klass)
 {
-       int i, count_generic = 0;
+       int i, count_generic = 0, mcount;
        GList *list = NULL, *tmp;
        if (generic_array_method_num)
                return generic_array_method_num;
        mono_class_setup_methods (klass->parent); /*This is setting up System.Array*/
        g_assert (!mono_class_has_failure (klass->parent)); /*So hitting this assert is a huge problem*/
-       for (i = 0; i < klass->parent->method.count; i++) {
+       mcount = mono_class_get_method_count (klass->parent);
+       for (i = 0; i < mcount; i++) {
                MonoMethod *m = klass->parent->methods [i];
                if (!strncmp (m->name, "InternalArray__", 15)) {
                        count_generic++;
@@ -5243,7 +5256,8 @@ mono_class_init (MonoClass *klass)
                                if (mono_class_has_failure (klass))
                                        goto leave;
 
-                               for (i = 0; i < klass->method.count; ++i) {
+                               int mcount = mono_class_get_method_count (klass);
+                               for (i = 0; i < mcount; ++i) {
                                        MonoMethod *method = klass->methods [i];
                                        if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && 
                                                (strcmp (".cctor", method->name) == 0)) {
@@ -5289,15 +5303,9 @@ mono_class_init (MonoClass *klass)
 
        mono_stats.initialized_class_count++;
 
-       if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) {
-               MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
-
+       if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic)
                mono_stats.generic_class_count++;
 
-               klass->method = gklass->method;
-               klass->field = gklass->field;
-       }
-
        if (mono_class_is_ginst (klass) || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes))
                klass->nested_classes_inited = TRUE;
        klass->ghcimpl = ghcimpl;
@@ -5309,7 +5317,7 @@ mono_class_init (MonoClass *klass)
                klass->has_finalize_inited = TRUE;
        }
        if (klass->rank)
-               klass->method.count = array_method_count;
+               mono_class_set_method_count (klass, array_method_count);
 
        mono_loader_unlock ();
        locked = FALSE;
@@ -5664,12 +5672,12 @@ mono_class_setup_parent (MonoClass *klass, MonoClass *parent)
  *  - supertypes: array of classes: each element has a class in the hierarchy
  *    starting from @class up to System.Object
  * 
- * LOCKING: This function is atomic, in case of contention we waste memory.
+ * LOCKING: Acquires the loader lock.
  */
 void
 mono_class_setup_supertypes (MonoClass *klass)
 {
-       int ms;
+       int ms, idepth;
        MonoClass **supertypes;
 
        mono_atomic_load_acquire (supertypes, MonoClass **, &klass->supertypes);
@@ -5679,15 +5687,15 @@ mono_class_setup_supertypes (MonoClass *klass)
        if (klass->parent && !klass->parent->supertypes)
                mono_class_setup_supertypes (klass->parent);
        if (klass->parent)
-               klass->idepth = klass->parent->idepth + 1;
+               idepth = klass->parent->idepth + 1;
        else
-               klass->idepth = 1;
+               idepth = 1;
 
-       ms = MAX (MONO_DEFAULT_SUPERTABLE_SIZE, klass->idepth);
+       ms = MAX (MONO_DEFAULT_SUPERTABLE_SIZE, idepth);
        supertypes = (MonoClass **)mono_class_alloc0 (klass, sizeof (MonoClass *) * ms);
 
        if (klass->parent) {
-               CHECKED_METADATA_WRITE_PTR ( supertypes [klass->idepth - 1] , klass );
+               CHECKED_METADATA_WRITE_PTR ( supertypes [idepth - 1] , klass );
 
                int supertype_idx;
                for (supertype_idx = 0; supertype_idx < klass->parent->idepth; supertype_idx++)
@@ -5696,7 +5704,14 @@ mono_class_setup_supertypes (MonoClass *klass)
                CHECKED_METADATA_WRITE_PTR ( supertypes [0] , klass );
        }
 
-       CHECKED_METADATA_WRITE_PTR_ATOMIC ( klass->supertypes , supertypes );
+       mono_memory_barrier ();
+
+       mono_loader_lock ();
+       klass->idepth = idepth;
+       /* Needed so idepth is visible before supertypes is set */
+       mono_memory_barrier ();
+       klass->supertypes = supertypes;
+       mono_loader_unlock ();
 }
 
 static gboolean
@@ -5906,19 +5921,14 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
 
        if (cols [MONO_TYPEDEF_FIELD_LIST] && 
            cols [MONO_TYPEDEF_FIELD_LIST] <= image->tables [MONO_TABLE_FIELD].rows)
-               klass->field.count = field_last - first_field_idx;
-       else
-               klass->field.count = 0;
-
+               mono_class_set_field_count (klass, field_last - first_field_idx);
        if (cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows)
-               klass->method.count = method_last - first_method_idx;
-       else
-               klass->method.count = 0;
+               mono_class_set_method_count (klass, method_last - first_method_idx);
 
        /* reserve space to store vector pointer in arrays */
        if (mono_is_corlib_image (image) && !strcmp (nspace, "System") && !strcmp (name, "Array")) {
                klass->instance_size += 2 * sizeof (gpointer);
-               g_assert (klass->field.count == 0);
+               g_assert (mono_class_get_field_count (klass) == 0);
        }
 
        if (klass->enumtype) {
@@ -6043,7 +6053,6 @@ mono_generic_class_get_class (MonoGenericClass *gclass)
        
        klass->image = gklass->image;
        klass->type_token = gklass->type_token;
-       klass->field.count = gklass->field.count;
 
        klass->class_kind = MONO_CLASS_GINST;
        //FIXME add setter
@@ -6962,6 +6971,7 @@ mono_class_get_field_idx (MonoClass *klass, int idx)
 
        while (klass) {
                int first_field_idx = mono_class_get_first_field_idx (klass);
+               int fcount = mono_class_get_field_count (klass);
                if (klass->image->uncompressed_metadata) {
                        /* 
                         * first_field_idx points to the FieldPtr table, while idx points into the
@@ -6971,13 +6981,13 @@ mono_class_get_field_idx (MonoClass *klass, int idx)
                        const char *name = mono_metadata_string_heap (klass->image, mono_metadata_decode_row_col (&klass->image->tables [MONO_TABLE_FIELD], idx, MONO_FIELD_NAME));
                        int i;
 
-                       for (i = 0; i < klass->field.count; ++i)
+                       for (i = 0; i < fcount; ++i)
                                if (mono_field_get_name (&klass->fields [i]) == name)
                                        return &klass->fields [i];
                        g_assert_not_reached ();
                } else {                        
-                       if (klass->field.count) {
-                               if ((idx >= first_field_idx) && (idx < first_field_idx + klass->field.count)){
+                       if (fcount) {
+                               if ((idx >= first_field_idx) && (idx < first_field_idx + fcount)){
                                        return &klass->fields [idx - first_field_idx];
                                }
                        }
@@ -7044,7 +7054,8 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp
                return NULL;
 
        while (klass) {
-               for (i = 0; i < klass->field.count; ++i) {
+               int fcount = mono_class_get_field_count (klass);
+               for (i = 0; i < fcount; ++i) {
                        MonoClassField *field = &klass->fields [i];
 
                        if (strcmp (name, mono_field_get_name (field)) != 0)
@@ -7083,7 +7094,8 @@ mono_class_get_field_token (MonoClassField *field)
                if (!klass->fields)
                        return 0;
                int first_field_idx = mono_class_get_first_field_idx (klass);
-               for (i = 0; i < klass->field.count; ++i) {
+               int fcount = mono_class_get_field_count (klass);
+               for (i = 0; i < fcount; ++i) {
                        if (&klass->fields [i] == field) {
                                int idx = first_field_idx + i + 1;
 
@@ -7103,8 +7115,7 @@ static int
 mono_field_get_index (MonoClassField *field)
 {
        int index = field - field->parent->fields;
-
-       g_assert (index >= 0 && index < field->parent->field.count);
+       g_assert (index >= 0 && index < mono_class_get_field_count (field->parent));
 
        return index;
 }
@@ -7129,7 +7140,7 @@ mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_typ
 
                mono_class_alloc_ext (klass);
 
-               def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * klass->field.count);
+               def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * mono_class_get_field_count (klass));
 
                mono_image_lock (klass->image);
                mono_memory_barrier ();
@@ -9080,7 +9091,7 @@ mono_class_get_byref_type (MonoClass *klass)
 int
 mono_class_num_fields (MonoClass *klass)
 {
-       return klass->field.count;
+       return mono_class_get_field_count (klass);
 }
 
 /**
@@ -9092,7 +9103,7 @@ mono_class_num_fields (MonoClass *klass)
 int
 mono_class_num_methods (MonoClass *klass)
 {
-       return klass->method.count;
+       return mono_class_get_method_count (klass);
 }
 
 /**
@@ -9146,7 +9157,7 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter)
                if (mono_class_has_failure (klass))
                        return NULL;
                /* start from the first */
-               if (klass->field.count) {
+               if (mono_class_get_field_count (klass)) {
                        *iter = &klass->fields [0];
                        return &klass->fields [0];
                } else {
@@ -9156,7 +9167,7 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter)
        }
        field = (MonoClassField *)*iter;
        field++;
-       if (field < &klass->fields [klass->field.count]) {
+       if (field < &klass->fields [mono_class_get_field_count (klass)]) {
                *iter = field;
                return field;
        }
@@ -9191,7 +9202,7 @@ mono_class_get_methods (MonoClass* klass, gpointer *iter)
                if (!klass->methods)
                        return NULL;
                /* start from the first */
-               if (klass->method.count) {
+               if (mono_class_get_method_count (klass)) {
                        *iter = &klass->methods [0];
                        return klass->methods [0];
                } else {
@@ -9201,7 +9212,7 @@ mono_class_get_methods (MonoClass* klass, gpointer *iter)
        }
        method = (MonoMethod **)*iter;
        method++;
-       if (method < &klass->methods [klass->method.count]) {
+       if (method < &klass->methods [mono_class_get_method_count (klass)]) {
                *iter = method;
                return *method;
        }
@@ -9236,12 +9247,13 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                        method = (MonoMethod **)*iter;
                        method++;
                }
-               while (method < &klass->methods [klass->method.count]) {
+               int mcount = mono_class_get_method_count (klass);
+               while (method < &klass->methods [mcount]) {
                        if (*method && ((*method)->flags & METHOD_ATTRIBUTE_VIRTUAL))
                                break;
                        method ++;
                }
-               if (method < &klass->methods [klass->method.count]) {
+               if (method < &klass->methods [mcount]) {
                        *iter = method;
                        return *method;
                } else {
@@ -9259,7 +9271,8 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                }
 
                int first_idx = mono_class_get_first_method_idx (klass);
-               for (i = start_index; i < klass->method.count; ++i) {
+               int mcount = mono_class_get_method_count (klass);
+               for (i = start_index; i < mcount; ++i) {
                        guint32 flags;
 
                        /* first_idx points into the methodptr table */
@@ -9269,7 +9282,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
                                break;
                }
 
-               if (i < klass->method.count) {
+               if (i < mcount) {
                        MonoError error;
                        res = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | (first_idx + i + 1), klass, NULL, &error);
                        mono_error_cleanup (&error); /* FIXME don't swallow the error */
@@ -9627,7 +9640,7 @@ mono_field_get_rva (MonoClassField *field)
        if (!klass->ext || !klass->ext->field_def_values) {
                mono_class_alloc_ext (klass);
 
-               field_def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * klass->field.count);
+               field_def_values = (MonoFieldDefaultValue *)mono_class_alloc0 (klass, sizeof (MonoFieldDefaultValue) * mono_class_get_field_count (klass));
 
                mono_image_lock (klass->image);
                if (!klass->ext->field_def_values)
@@ -9830,7 +9843,8 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in
 
        /* Search directly in the metadata to avoid calling setup_methods () */
        int first_idx = mono_class_get_first_method_idx (klass);
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                MonoError error;
                guint32 cols [MONO_METHOD_SIZE];
                MonoMethod *method;
@@ -9902,7 +9916,8 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p
                 */
                if (!klass->methods)
                        return NULL;
-               for (i = 0; i < klass->method.count; ++i) {
+               int mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        MonoMethod *method = klass->methods [i];
 
                        if (method->name[0] == name [0] && 
@@ -10578,7 +10593,7 @@ mono_class_is_valid_enum (MonoClass *klass)
        if (!found_base_field)
                return FALSE;
 
-       if (klass->method.count > 0) 
+       if (mono_class_get_method_count (klass) > 0)
                return FALSE;
 
        return TRUE;
@@ -10703,6 +10718,7 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
        MonoClass *klass = field->parent;
        MonoImage *image = klass->image;
        MonoClass *gtd = mono_class_is_ginst (klass) ? mono_class_get_generic_type_definition (klass) : NULL;
+       MonoType *ftype;
        int field_idx = field - klass->fields;
 
        mono_error_init (error);
@@ -10716,7 +10732,7 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                        g_free (full_name);
                }
 
-               field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
+               ftype = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
                if (!mono_error_ok (error)) {
                        char *full_name = mono_type_get_full_name (klass);
                        mono_class_set_type_load_failure (klass, "Could not load instantiated type of field '%s:%s' (%d) due to: %s", full_name, field->name, field_idx, mono_error_get_message (error));
@@ -10755,13 +10771,15 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error)
                /* FIELD signature == 0x06 */
                g_assert (*sig == 0x06);
 
-               field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
-               if (!field->type) {
+               ftype = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
+               if (!ftype) {
                        char *full_name = mono_type_get_full_name (klass);
                        mono_class_set_type_load_failure (klass, "Could not load type of field '%s:%s' (%d) due to: %s", full_name, field->name, field_idx, mono_error_get_message (error));
                        g_free (full_name);
                }
        }
+       mono_memory_barrier ();
+       field->type = ftype;
 }
 
 static guint32
@@ -10811,7 +10829,7 @@ mono_class_get_fields_lazy (MonoClass* klass, gpointer *iter)
                if (!klass->fields)
                        return NULL;
                /* start from the first */
-               if (klass->field.count) {
+               if (mono_class_get_field_count (klass)) {
                        *iter = &klass->fields [0];
                        return (MonoClassField *)*iter;
                } else {
@@ -10821,7 +10839,7 @@ mono_class_get_fields_lazy (MonoClass* klass, gpointer *iter)
        }
        field = (MonoClassField *)*iter;
        field++;
-       if (field < &klass->fields [klass->field.count]) {
+       if (field < &klass->fields [mono_class_get_field_count (klass)]) {
                *iter = field;
                return (MonoClassField *)*iter;
        }
index c918d3787df79c18fc1741cfc5565c9afc7b0998..cf61058a3a7525b92fa2ad8c0f355db5b1289bd0 100644 (file)
@@ -360,7 +360,8 @@ cominterop_get_method_interface (MonoMethod* method)
                                gboolean found = FALSE;
                                ic = (MonoClass *)g_ptr_array_index (ifaces, i);
                                offset = mono_class_interface_offset (method->klass, ic);
-                               for (j = 0; j < ic->method.count; ++j) {
+                               int mcount = mono_class_get_method_count (ic);
+                               for (j = 0; j < mcount; ++j) {
                                        if (method->klass->vtable [j + offset] == method) {
                                                found = TRUE;
                                                break;
@@ -400,7 +401,8 @@ cominterop_get_com_slot_for_method (MonoMethod* method)
                ic = cominterop_get_method_interface (method);
                offset = mono_class_interface_offset (method->klass, ic);
                g_assert(offset >= 0);
-               for(i = 0; i < ic->method.count; ++i) {
+               int mcount = mono_class_get_method_count (ic);
+               for(i = 0; i < mcount; ++i) {
                        if (method->klass->vtable [i + offset] == method)
                        {
                                slot = ic->methods[i]->slot;
@@ -2022,7 +2024,7 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                start_slot = 7;
        }
        else {
-               method_count += iface->method.count;
+               method_count += mono_class_get_method_count (iface);
                start_slot = cominterop_get_com_slot_begin (iface);
                iface = NULL;
        }
@@ -2037,7 +2039,7 @@ cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error
                        memcpy (vtable+3, idispatch, sizeof (idispatch));
 
                iface = itf;
-               for (i = iface->method.count-1; i >= 0;i--) {
+               for (i = mono_class_get_method_count (iface) - 1; i >= 0; i--) {
                        int param_index = 0;
                        MonoMethodBuilder *mb;
                        MonoMarshalSpec ** mspecs;
index 20fd8de75215b2b5ce726ba34a0ae9d763915c57..600a27e0765ba20e8109fb7678ec505053d6e17d 100644 (file)
@@ -120,7 +120,8 @@ static guint32
 find_field_index (MonoClass *klass, MonoClassField *field) {
        int i;
 
-       for (i = 0; i < klass->field.count; ++i) {
+       int fcount = mono_class_get_field_count (klass);
+       for (i = 0; i < fcount; ++i) {
                if (field == &klass->fields [i])
                        return mono_class_get_first_field_idx (klass) + 1 + i;
        }
index 0f54ea16dc0211be3e891e3d9e1a30d0e57cd9c1..9b5686568da3491507fa7ea5ff90469edea9dd81 100644 (file)
@@ -2099,7 +2099,7 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
                MonoClass *klass = field->parent;
                int fidx = field - klass->fields;
 
-               g_assert (fidx >= 0 && fidx < klass->field.count);
+               g_assert (fidx >= 0 && fidx < mono_class_get_field_count (klass));
                g_assert (klass->ext);
                g_assert (klass->ext->field_def_values);
                def_type = klass->ext->field_def_values [fidx].def_type;
@@ -5107,7 +5107,8 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
        mono_class_setup_methods (method->klass);
        if (mono_class_has_failure (method->klass))
                return NULL;
-       for (i = 0; i < method->klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (method->klass);
+       for (i = 0; i < mcount; ++i) {
                if (method->klass->methods [i] == method) {
                        offset = i;
                        break;
@@ -5116,7 +5117,7 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
        mono_class_setup_methods (klass);
        if (mono_class_has_failure (klass))
                return NULL;
-       g_assert (offset >= 0 && offset < klass->method.count);
+       g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
        return klass->methods [offset];
 }
 
index 3d76058d23314ce3dffb7247e88033eb50acdcf6..9e09748c344ba714c8e4002ed87f1531f690eb2d 100644 (file)
@@ -365,7 +365,8 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
        /* FIXME: !mono_class_is_ginst (from_class) condition causes test failures. */
        if (klass->type_token && !image_is_dynamic (klass->image) && !klass->methods && !klass->rank && klass == from_class && !mono_class_is_ginst (from_class)) {
                int first_idx = mono_class_get_first_method_idx (klass);
-               for (i = 0; i < klass->method.count; ++i) {
+               int mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        guint32 cols [MONO_METHOD_SIZE];
                        MonoMethod *method;
                        const char *m_name;
@@ -404,7 +405,8 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
 
                return NULL;
        }
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                MonoMethod *m = klass->methods [i];
                MonoMethodSignature *msig;
 
@@ -432,7 +434,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
                }
        }
 
-       if (i < klass->method.count)
+       if (i < mcount)
                return mono_class_get_method_by_index (from_class, i);
        return NULL;
 }
@@ -752,7 +754,8 @@ mono_method_search_in_array_class (MonoClass *klass, const char *name, MonoMetho
 
        mono_class_setup_methods (klass);
        g_assert (!mono_class_has_failure (klass)); /*FIXME this should not fail, right?*/
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                MonoMethod *method = klass->methods [i];
                if (strcmp (method->name, name) == 0 && sig->param_count == method->signature->param_count)
                        return method;
@@ -2622,7 +2625,8 @@ mono_method_get_index (MonoMethod *method)
        if (mono_class_has_failure (klass))
                return 0;
        int first_idx = mono_class_get_first_method_idx (klass);
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                if (method == klass->methods [i]) {
                        if (klass->image->uncompressed_metadata)
                                return mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, first_idx + i + 1);
index a743f83f6300731c27ee5dc55c9da46bcb76ef24..11b688dbea39934fbf45e03c95b4a219d89a5edb 100644 (file)
@@ -1928,10 +1928,12 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
        }
 }
 
-static int offset_of_first_nonstatic_field(MonoClass *klass)
+static int
+offset_of_first_nonstatic_field (MonoClass *klass)
 {
        int i;
-       for (i = 0; i < klass->field.count; i++) {
+       int fcount = mono_class_get_field_count (klass);
+       for (i = 0; i < fcount; i++) {
                if (!(klass->fields[i].type->attrs & FIELD_ATTRIBUTE_STATIC) && !mono_field_is_deleted (&klass->fields[i]))
                        return klass->fields[i].offset - sizeof (MonoObject);
        }
index 1a60d2d85f36320dfb29e68a5d64e3dee4793a03..46269e2a377c60580f970ce2fd6974742e728755 100644 (file)
@@ -384,6 +384,7 @@ struct _MonoInternalThread {
        gint32 priority;
        GPtrArray *owned_mutexes;
        MonoOSEvent *suspended;
+       gint32 self_suspended; // TRUE | FALSE
        /* 
         * These fields are used to avoid having to increment corlib versions
         * when a new field is added to this structure.
index c25a107fdeb502712987c0c7b5671e8258b1f49d..07982207428e2ed46b9e00eb57eed2bd98b78296 100644 (file)
@@ -1403,7 +1403,8 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
 
                mono_class_setup_methods (iface);
                vt_slot = interface_offset;
-               for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
+               int mcount = mono_class_get_method_count (iface);
+               for (method_slot_in_interface = 0; method_slot_in_interface < mcount; method_slot_in_interface++) {
                        MonoMethod *method;
 
                        if (slot_num >= 0 && mono_class_is_ginst (iface)) {
@@ -1438,14 +1439,15 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
                for (list_item = extra_interfaces; list_item != NULL; list_item=list_item->next) {
                        MonoClass* iface = (MonoClass *)list_item->data;
                        int method_slot_in_interface;
-                       for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
+                       int mcount = mono_class_get_method_count (iface);
+                       for (method_slot_in_interface = 0; method_slot_in_interface < mcount; method_slot_in_interface++) {
                                MonoMethod *method = mono_class_get_method_by_index (iface, method_slot_in_interface);
 
                                if (method->is_generic)
                                        has_generic_virtual = TRUE;
                                add_imt_builder_entry (imt_builder, method, &imt_collisions_bitmap, interface_offset + method_slot_in_interface, slot_num);
                        }
-                       interface_offset += iface->method.count;
+                       interface_offset += mcount;
                }
        }
        for (i = 0; i < MONO_IMT_SIZE; ++i) {
index b93c72203221ac36fd6a656ca7a2d5fa4dff61a0..f817f956297457016c5c2a7665d87b96fdd59da1 100644 (file)
@@ -206,7 +206,8 @@ get_default_ctor (MonoClass *klass)
        if (!klass->methods)
                return NULL;
 
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                MonoMethodSignature *sig;
                MonoMethod *method = klass->methods [i];
 
index 9b9de7180ed66d596ee8c3034eca4ec2dad91c05..22ff814df699bdcad3b99b174a2f25ee433e93ea 100644 (file)
@@ -248,30 +248,35 @@ sgen_is_thread_in_current_stw (SgenThreadInfo *info, int *reason)
 static void
 sgen_unified_suspend_stop_world (void)
 {
-       int restart_counter;
        int sleep_duration = -1;
 
        mono_threads_begin_global_suspend ();
        THREADS_STW_DEBUG ("[GC-STW-BEGIN][%p] *** BEGIN SUSPEND *** \n", mono_thread_info_get_tid (mono_thread_info_current ()));
 
        FOREACH_THREAD (info) {
-               int reason;
                info->client_info.skip = FALSE;
                info->client_info.suspend_done = FALSE;
-               if (sgen_is_thread_in_current_stw (info, &reason)) {
-                       info->client_info.skip = !mono_thread_info_begin_suspend (info);
-                       THREADS_STW_DEBUG ("[GC-STW-BEGIN-SUSPEND] SUSPEND thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
-               } else {
+
+               int reason;
+               if (!sgen_is_thread_in_current_stw (info, &reason)) {
                        THREADS_STW_DEBUG ("[GC-STW-BEGIN-SUSPEND] IGNORE thread %p skip %s reason %d\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false", reason);
+                       continue;
                }
+
+               info->client_info.skip = !mono_thread_info_begin_suspend (info);
+
+               THREADS_STW_DEBUG ("[GC-STW-BEGIN-SUSPEND] SUSPEND thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
        } FOREACH_THREAD_END
 
        mono_thread_info_current ()->client_info.suspend_done = TRUE;
        mono_threads_wait_pending_operations ();
 
        for (;;) {
-               restart_counter = 0;
+               gint restart_counter = 0;
+
                FOREACH_THREAD (info) {
+                       gint suspend_count;
+
                        int reason = 0;
                        if (info->client_info.suspend_done || !sgen_is_thread_in_current_stw (info, &reason)) {
                                THREADS_STW_DEBUG ("[GC-STW-RESTART] IGNORE RESUME thread %p not been processed done %d current %d reason %d\n", mono_thread_info_get_tid (info), info->client_info.suspend_done, !sgen_is_thread_in_current_stw (info, NULL), reason);
@@ -284,27 +289,28 @@ sgen_unified_suspend_stop_world (void)
                        - We haven't accepted the previous suspend as good.
                        - We haven't gave up on it for this STW (it's either bad or asked not to)
                        */
-                       if (mono_thread_info_in_critical_location (info)) {
-                               gboolean res;
-                               gint suspend_count = mono_thread_info_suspend_count (info);
-                               if (!(suspend_count == 1))
-                                       g_error ("[%p] suspend_count = %d, but should be 1", mono_thread_info_get_tid (info), suspend_count);
-                               res = mono_thread_info_begin_resume (info);
-                               if (res)
-                                       ++restart_counter;
-                               else
-                                       info->client_info.skip = TRUE;
-                               THREADS_STW_DEBUG ("[GC-STW-RESTART] RESTART thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
-                       } else {
-                               THREADS_STW_DEBUG ("[GC-STW-RESTART] DONE thread %p deemed fully suspended\n", mono_thread_info_get_tid (info));
-                               g_assert (!info->client_info.in_critical_region);
+                       if (!mono_thread_info_in_critical_location (info)) {
                                info->client_info.suspend_done = TRUE;
+
+                               THREADS_STW_DEBUG ("[GC-STW-RESTART] DONE thread %p deemed fully suspended\n", mono_thread_info_get_tid (info));
+                               continue;
                        }
+
+                       suspend_count = mono_thread_info_suspend_count (info);
+                       if (!(suspend_count == 1))
+                               g_error ("[%p] suspend_count = %d, but should be 1", mono_thread_info_get_tid (info), suspend_count);
+
+                       info->client_info.skip = !mono_thread_info_begin_resume (info);
+                       if (!info->client_info.skip)
+                               restart_counter += 1;
+
+                       THREADS_STW_DEBUG ("[GC-STW-RESTART] RESTART thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
                } FOREACH_THREAD_END
 
+               mono_threads_wait_pending_operations ();
+
                if (restart_counter == 0)
                        break;
-               mono_threads_wait_pending_operations ();
 
                if (sleep_duration < 0) {
                        mono_thread_info_yield ();
@@ -321,47 +327,51 @@ sgen_unified_suspend_stop_world (void)
                                continue;
                        }
 
-                       if (mono_thread_info_is_running (info)) {
-                               gboolean res = mono_thread_info_begin_suspend (info);
-                               if (!res)
-                                       info->client_info.skip = TRUE;
-                               THREADS_STW_DEBUG ("[GC-STW-RESTART] SUSPEND thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
+                       if (!mono_thread_info_is_running (info)) {
+                               THREADS_STW_DEBUG ("[GC-STW-RESTART] IGNORE SUSPEND thread %p not running\n", mono_thread_info_get_tid (info));
+                               continue;
                        }
+
+                       info->client_info.skip = !mono_thread_info_begin_suspend (info);
+
+                       THREADS_STW_DEBUG ("[GC-STW-RESTART] SUSPEND thread %p skip %s\n", mono_thread_info_get_tid (info), info->client_info.skip ? "true" : "false");
                } FOREACH_THREAD_END
 
                mono_threads_wait_pending_operations ();
        }
 
        FOREACH_THREAD (info) {
+               gpointer stopped_ip;
+
                int reason = 0;
-               if (sgen_is_thread_in_current_stw (info, &reason)) {
-                       gpointer stopped_ip;
+               if (!sgen_is_thread_in_current_stw (info, &reason)) {
+                       g_assert (!info->client_info.suspend_done || info == mono_thread_info_current ());
 
-                       g_assert (info->client_info.suspend_done);
+                       THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is NOT suspended, reason %d\n", mono_thread_info_get_tid (info), reason);
+                       continue;
+               }
 
-                       info->client_info.ctx = mono_thread_info_get_suspend_state (info)->ctx;
+               g_assert (info->client_info.suspend_done);
 
-                       /* Once we remove the old suspend code, we should move sgen to directly access the state in MonoThread */
-                       info->client_info.stack_start = (gpointer) ((char*)MONO_CONTEXT_GET_SP (&info->client_info.ctx) - REDZONE_SIZE);
+               info->client_info.ctx = mono_thread_info_get_suspend_state (info)->ctx;
 
-                       /* altstack signal handler, sgen can't handle them, mono-threads should have handled this. */
-                       if (!info->client_info.stack_start
-                                || info->client_info.stack_start < info->client_info.stack_start_limit
-                                || info->client_info.stack_start >= info->client_info.stack_end) {
-                               g_error ("BAD STACK: stack_start = %p, stack_start_limit = %p, stack_end = %p",
-                                       info->client_info.stack_start, info->client_info.stack_start_limit, info->client_info.stack_end);
-                       }
+               /* Once we remove the old suspend code, we should move sgen to directly access the state in MonoThread */
+               info->client_info.stack_start = (gpointer) ((char*)MONO_CONTEXT_GET_SP (&info->client_info.ctx) - REDZONE_SIZE);
 
-                       stopped_ip = (gpointer) (MONO_CONTEXT_GET_IP (&info->client_info.ctx));
+               /* altstack signal handler, sgen can't handle them, mono-threads should have handled this. */
+               if (!info->client_info.stack_start
+                        || info->client_info.stack_start < info->client_info.stack_start_limit
+                        || info->client_info.stack_start >= info->client_info.stack_end) {
+                       g_error ("BAD STACK: stack_start = %p, stack_start_limit = %p, stack_end = %p",
+                               info->client_info.stack_start, info->client_info.stack_start_limit, info->client_info.stack_end);
+               }
 
-                       THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is suspended, stopped_ip = %p, stack = %p -> %p\n",
-                               mono_thread_info_get_tid (info), stopped_ip, info->client_info.stack_start, info->client_info.stack_start ? info->client_info.stack_end : NULL);
+               stopped_ip = (gpointer) (MONO_CONTEXT_GET_IP (&info->client_info.ctx));
 
-                       binary_protocol_thread_suspend ((gpointer) mono_thread_info_get_tid (info), stopped_ip);
-               } else {
-                       THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is NOT suspended, reason %d\n", mono_thread_info_get_tid (info), reason);
-                       g_assert (!info->client_info.suspend_done || info == mono_thread_info_current ());
-               }
+               binary_protocol_thread_suspend ((gpointer) mono_thread_info_get_tid (info), stopped_ip);
+
+               THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is suspended, stopped_ip = %p, stack = %p -> %p\n",
+                       mono_thread_info_get_tid (info), stopped_ip, info->client_info.stack_start, info->client_info.stack_start ? info->client_info.stack_end : NULL);
        } FOREACH_THREAD_END
 }
 
index 10a916758df11f2e6d84f09e1f5a80634b3c473a..5b411fd05fe962e5a20dd28d65b86a2d49b360c5 100644 (file)
@@ -2939,11 +2939,13 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
        if (!mono_class_get_generic_class (klass)->need_sync)
                return TRUE;
 
-       if (klass->method.count != gklass->method.count) {
-               klass->method.count = gklass->method.count;
-               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+       int mcount = mono_class_get_method_count (klass);
+       int gmcount = mono_class_get_method_count (gklass);
+       if (mcount != gmcount) {
+               mono_class_set_method_count (klass, gmcount);
+               klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
 
-               for (i = 0; i < klass->method.count; i++) {
+               for (i = 0; i < gmcount; i++) {
                        klass->methods [i] = mono_class_inflate_generic_method_full_checked (
                                gklass->methods [i], klass, mono_class_get_context (klass), error);
                        mono_error_assert_ok (error);
@@ -2968,11 +2970,13 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
                klass->interfaces_inited = 1;
        }
 
-       if (klass->field.count != gklass->field.count) {
-               klass->field.count = gklass->field.count;
-               klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
+       int fcount = mono_class_get_field_count (klass);
+       int gfcount = mono_class_get_field_count (gklass);
+       if (fcount != gfcount) {
+               mono_class_set_field_count (klass, gfcount);
+               klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
 
-               for (i = 0; i < klass->field.count; i++) {
+               for (i = 0; i < gfcount; i++) {
                        klass->fields [i] = gklass->fields [i];
                        klass->fields [i].parent = klass;
                        klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
@@ -3032,7 +3036,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
        if (tb) {
                num = tb->ctors? mono_array_length (tb->ctors): 0;
                num += tb->num_methods;
-               klass->method.count = num;
+               mono_class_set_method_count (klass, num);
                klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
                num = tb->ctors? mono_array_length (tb->ctors): 0;
                for (i = 0; i < num; ++i) {
@@ -3069,9 +3073,10 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
                }
        }
 
-       if (mono_class_is_interface (klass)) {
+       if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
                int slot_num = 0;
-               for (i = 0; i < klass->method.count; ++i) {
+               int mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        MonoMethod *im = klass->methods [i];
                        if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
                                im->slot = slot_num++;
@@ -3198,7 +3203,8 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                instance_size = sizeof (MonoObject);
        }
 
-       klass->field.count = tb->num_fields;
+       int fcount = tb->num_fields;
+       mono_class_set_field_count (klass, fcount);
 
        mono_error_init (error);
 
@@ -3207,9 +3213,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                instance_size += tb->class_size;
        }
        
-       klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
+       klass->fields = image_g_new0 (image, MonoClassField, fcount);
        mono_class_alloc_ext (klass);
-       klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
+       klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
        /*
        This is, guess what, a hack.
        The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
@@ -3219,7 +3225,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        */
        klass->size_inited = 1;
 
-       for (i = 0; i < klass->field.count; ++i) {
+       for (i = 0; i < fcount; ++i) {
                MonoArray *rva_data;
                fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
index 315183a7762c421abfc3a07ef7c6c672268d02f8..83ac3dd994b2e47ec5e10becd6e65abd8495a717 100644 (file)
@@ -453,6 +453,10 @@ static void thread_cleanup (MonoInternalThread *thread)
                thread->thread_pinning_ref = NULL;
        }
 
+       g_assert (thread->suspended);
+       mono_os_event_destroy (thread->suspended);
+       g_free (thread->suspended);
+       thread->suspended = NULL;
 }
 
 /*
@@ -584,7 +588,7 @@ create_internal_thread_object (void)
        thread->priority = MONO_THREAD_PRIORITY_NORMAL;
 
        thread->suspended = g_new0 (MonoOSEvent, 1);
-       mono_os_event_init (thread->suspended, TRUE, TRUE);
+       mono_os_event_init (thread->suspended, TRUE);
 
        return thread;
 }
@@ -1288,11 +1292,6 @@ ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThre
                this_obj->name = NULL;
                g_free (name);
        }
-
-       g_assert (this_obj->suspended);
-       mono_os_event_destroy (this_obj->suspended);
-       g_free (this_obj->suspended);
-       this_obj->suspended = NULL;
 }
 
 void
@@ -2335,8 +2334,7 @@ mono_thread_suspend (MonoInternalThread *thread)
        }
        
        thread->state |= ThreadState_SuspendRequested;
-       if (mono_threads_is_coop_enabled ())
-               mono_os_event_reset (thread->suspended);
+       mono_os_event_reset (thread->suspended);
 
        if (thread == mono_thread_internal_current ()) {
                /* calls UNLOCK_THREAD (thread) */
@@ -2364,9 +2362,8 @@ mono_thread_resume (MonoInternalThread *thread)
 {
        if ((thread->state & ThreadState_SuspendRequested) != 0) {
                // MOSTLY_ASYNC_SAFE_PRINTF ("RESUME (1) thread %p\n", thread_get_tid (thread));
-               if (mono_threads_is_coop_enabled ())
-                       mono_os_event_set (thread->suspended);
                thread->state &= ~ThreadState_SuspendRequested;
+               mono_os_event_set (thread->suspended);
                return TRUE;
        }
 
@@ -2381,9 +2378,9 @@ mono_thread_resume (MonoInternalThread *thread)
 
        // MOSTLY_ASYNC_SAFE_PRINTF ("RESUME (3) thread %p\n", thread_get_tid (thread));
 
-       if (mono_threads_is_coop_enabled ()) {
-               mono_os_event_set (thread->suspended);
-       } else {
+       mono_os_event_set (thread->suspended);
+
+       if (!thread->self_suspended) {
                UNLOCK_THREAD (thread);
 
                /* Awake the thread */
@@ -2860,7 +2857,7 @@ void mono_thread_init (MonoThreadStartCB start_cb,
        mono_os_mutex_init_recursive(&interlocked_mutex);
        mono_os_mutex_init_recursive(&joinable_threads_mutex);
        
-       mono_os_event_init (&background_change_event, TRUE, FALSE);
+       mono_os_event_init (&background_change_event, FALSE);
        
        mono_init_static_data_info (&thread_static_info);
        mono_init_static_data_info (&context_static_info);
@@ -2930,42 +2927,7 @@ struct wait_data
 };
 
 static void
-wait_for_tids (struct wait_data *wait, guint32 timeout)
-{
-       guint32 i;
-       MonoThreadInfoWaitRet ret;
-       
-       THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
-
-       MONO_ENTER_GC_SAFE;
-       ret = mono_thread_info_wait_multiple_handle(wait->handles, wait->num, NULL, TRUE, timeout, TRUE);
-       MONO_EXIT_GC_SAFE;
-
-       if(ret==MONO_THREAD_INFO_WAIT_RET_FAILED) {
-               /* See the comment in build_wait_tids() */
-               THREAD_DEBUG (g_message ("%s: Wait failed", __func__));
-               return;
-       }
-       
-       for(i=0; i<wait->num; i++)
-               mono_threads_close_thread_handle (wait->handles [i]);
-
-       if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT)
-               return;
-
-       for(i=0; i<wait->num; i++) {
-               MonoInternalThread *internal;
-
-               internal = wait->threads [i];
-
-               mono_threads_lock ();
-               if (mono_g_hash_table_lookup (threads, (gpointer) internal->tid) == internal)
-                       g_error ("%s: failed to call mono_thread_detach_internal on thread %p, InternalThread: %p", __func__, internal->tid, internal);
-               mono_threads_unlock ();
-       }
-}
-
-static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeout)
+wait_for_tids (struct wait_data *wait, guint32 timeout, gboolean check_state_change)
 {
        guint32 i;
        MonoThreadInfoWaitRet ret;
@@ -2976,16 +2938,19 @@ static void wait_for_tids_or_state_change (struct wait_data *wait, guint32 timeo
         * up if a thread changes to background mode. */
 
        MONO_ENTER_GC_SAFE;
-       ret = mono_thread_info_wait_multiple_handle (wait->handles, wait->num, &background_change_event, FALSE, timeout, TRUE);
+       if (check_state_change)
+               ret = mono_thread_info_wait_multiple_handle (wait->handles, wait->num, &background_change_event, FALSE, timeout, TRUE);
+       else
+               ret = mono_thread_info_wait_multiple_handle (wait->handles, wait->num, NULL, TRUE, timeout, TRUE);
        MONO_EXIT_GC_SAFE;
 
-       if(ret==MONO_THREAD_INFO_WAIT_RET_FAILED) {
+       if (ret == MONO_THREAD_INFO_WAIT_RET_FAILED) {
                /* See the comment in build_wait_tids() */
                THREAD_DEBUG (g_message ("%s: Wait failed", __func__));
                return;
        }
        
-       for(i=0; i<wait->num; i++)
+       for( i = 0; i < wait->num; i++)
                mono_threads_close_thread_handle (wait->handles [i]);
 
        if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT)
@@ -3162,14 +3127,13 @@ void mono_thread_manage (void)
        
                mono_os_event_reset (&background_change_event);
                wait->num=0;
-               /*We must zero all InternalThread pointers to avoid making the GC unhappy.*/
+               /* We must zero all InternalThread pointers to avoid making the GC unhappy. */
                memset (wait->threads, 0, MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS * SIZEOF_VOID_P);
                mono_g_hash_table_foreach (threads, build_wait_tids, wait);
                mono_threads_unlock ();
-               if(wait->num>0) {
+               if (wait->num > 0)
                        /* Something to wait for */
-                       wait_for_tids_or_state_change (wait, INFINITE);
-               }
+                       wait_for_tids (wait, INFINITE, TRUE);
                THREAD_DEBUG (g_message ("%s: I have %d threads after waiting.", __func__, wait->num));
        } while(wait->num>0);
 
@@ -3195,9 +3159,9 @@ void mono_thread_manage (void)
                mono_threads_unlock ();
 
                THREAD_DEBUG (g_message ("%s: wait->num is now %d", __func__, wait->num));
-               if(wait->num>0) {
+               if (wait->num > 0) {
                        /* Something to wait for */
-                       wait_for_tids (wait, INFINITE);
+                       wait_for_tids (wait, INFINITE, FALSE);
                }
        } while (wait->num > 0);
        
@@ -3288,8 +3252,8 @@ void mono_thread_suspend_all_other_threads (void)
                             || mono_gc_is_finalizer_internal_thread (thread)
                             || (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)
                        ) {
-                               //mono_threads_close_thread_handle (wait->handles [i]);
-                               wait->threads [i] = NULL; /* ignore this thread in next loop */
+                               mono_threads_close_thread_handle (wait->handles [i]);
+                               wait->threads [i] = NULL;
                                continue;
                        }
 
@@ -3300,7 +3264,7 @@ void mono_thread_suspend_all_other_threads (void)
                                (thread->state & ThreadState_Stopped) != 0) {
                                UNLOCK_THREAD (thread);
                                mono_threads_close_thread_handle (wait->handles [i]);
-                               wait->threads [i] = NULL; /* ignore this thread in next loop */
+                               wait->threads [i] = NULL;
                                continue;
                        }
 
@@ -3311,11 +3275,13 @@ void mono_thread_suspend_all_other_threads (void)
                                thread->state &= ~ThreadState_AbortRequested;
                        
                        thread->state |= ThreadState_SuspendRequested;
-                       if (mono_threads_is_coop_enabled ())
-                               mono_os_event_reset (thread->suspended);
+                       mono_os_event_reset (thread->suspended);
 
                        /* Signal the thread to suspend + calls UNLOCK_THREAD (thread) */
                        async_suspend_internal (thread, TRUE);
+
+                       mono_threads_close_thread_handle (wait->handles [i]);
+                       wait->threads [i] = NULL;
                }
                if (eventidx <= 0) {
                        /* 
@@ -3800,7 +3766,7 @@ mono_threads_abort_appdomain_threads (MonoDomain *domain, int timeout)
                         * We should wait for the threads either to abort, or to leave the
                         * domain. We can't do the latter, so we wait with a timeout.
                         */
-                       wait_for_tids (&user_data.wait, 100);
+                       wait_for_tids (&user_data.wait, 100, FALSE);
                }
 
                /* Update remaining time */
@@ -4833,6 +4799,8 @@ async_suspend_internal (MonoInternalThread *thread, gboolean interrupt)
 
        // MOSTLY_ASYNC_SAFE_PRINTF ("ASYNC SUSPEND thread %p\n", thread_get_tid (thread));
 
+       thread->self_suspended = FALSE;
+
        data.thread = thread;
        data.interrupt = interrupt;
        data.interrupt_token = NULL;
@@ -4849,32 +4817,26 @@ static void
 self_suspend_internal (void)
 {
        MonoInternalThread *thread;
+       MonoOSEvent *event;
+       MonoOSEventWaitRet res;
 
        thread = mono_thread_internal_current ();
 
        // MOSTLY_ASYNC_SAFE_PRINTF ("SELF SUSPEND thread %p\n", thread_get_tid (thread));
 
-       if (!mono_threads_is_coop_enabled ())
-               mono_thread_info_begin_self_suspend ();
+       thread->self_suspended = TRUE;
 
        thread->state &= ~ThreadState_SuspendRequested;
        thread->state |= ThreadState_Suspended;
 
        UNLOCK_THREAD (thread);
 
-       if (!mono_threads_is_coop_enabled ())
-               mono_thread_info_end_self_suspend ();
-       else {
-               MonoOSEvent *event;
-               MonoOSEventWaitRet res;
-
-               event = thread->suspended;
+       event = thread->suspended;
 
-               MONO_ENTER_GC_SAFE;
-               res = mono_os_event_wait_one (event, MONO_INFINITE_WAIT);
-               g_assert (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0);
-               MONO_EXIT_GC_SAFE;
-       }
+       MONO_ENTER_GC_SAFE;
+       res = mono_os_event_wait_one (event, MONO_INFINITE_WAIT);
+       g_assert (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0 || res == MONO_OS_EVENT_WAIT_RET_ALERTED);
+       MONO_EXIT_GC_SAFE;
 }
 
 /*
index baed2947614e4a0611992f45d62a2a541f89e3fb..106bae0725557f553a4fbb760eea7b3d04a9ee74 100644 (file)
@@ -471,7 +471,8 @@ mono_class_has_default_constructor (MonoClass *klass)
        if (mono_class_has_failure (klass))
                return FALSE;
 
-       for (i = 0; i < klass->method.count; ++i) {
+       int mcount = mono_class_get_method_count (klass);
+       for (i = 0; i < mcount; ++i) {
                method = klass->methods [i];
                if (mono_method_is_constructor (method) &&
                        mono_method_signature (method) &&
@@ -6117,7 +6118,8 @@ verify_class_for_overlapping_reference_fields (MonoClass *klass)
                if (mono_field_is_deleted (field) || (field->type->attrs & FIELD_ATTRIBUTE_STATIC))
                        continue;
 
-               for (j = i; j < klass->field.count; ++j) {
+               int fcount = mono_class_get_field_count (klass);
+               for (j = i; j < fcount; ++j) {
                        MonoClassField *other = &klass->fields [j];
                        int otherEnd = get_field_end (other);
                        if (mono_field_is_deleted (other) || (is_valuetype && !MONO_TYPE_IS_REFERENCE (other->type)) || (other->type->attrs & FIELD_ATTRIBUTE_STATIC))
index 6e2a7659ab210c11287023801acbb12cfdd8fdcd..e6d1ddb9363a3e77c740ac75e5c41169d40f738e 100644 (file)
@@ -586,57 +586,6 @@ done:
        mono_os_mutex_unlock (&scan_mutex);
 }
 
-typedef struct {
-       MonoW32HandleType type;
-       gboolean (*search_user_callback)(gpointer handle, gpointer data);
-       gpointer search_user_data;
-       gpointer handle;
-       gpointer handle_specific;
-} SearchData;
-
-static gboolean
-search_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
-{
-       SearchData *search_data = (SearchData*) user_data;
-
-       if (search_data->type != mono_w32handle_get_type (handle))
-               return FALSE;
-
-       if (!search_data->search_user_callback (handle, search_data->search_user_data))
-               return FALSE;
-
-       mono_w32handle_ref (handle);
-       search_data->handle = handle;
-       search_data->handle_specific = handle_specific;
-       return TRUE;
-}
-
-/* This might list some shared handles twice if they are already
- * opened by this process, and the check function returns FALSE the
- * first time.  Shared handles that are created during the search are
- * unreffed if the check function returns FALSE, so callers must not
- * rely on the handle persisting (unless the check function returns
- * TRUE)
- * The caller owns the returned handle.
- */
-gpointer mono_w32handle_search (MonoW32HandleType type,
-                             gboolean (*check)(gpointer test, gpointer user),
-                             gpointer user_data,
-                             gpointer *handle_specific,
-                             gboolean search_shared)
-{
-       SearchData search_data;
-
-       memset (&search_data, 0, sizeof (search_data));
-       search_data.type = type;
-       search_data.search_user_callback = check;
-       search_data.search_user_data = user_data;
-       mono_w32handle_foreach (search_callback, &search_data);
-       if (handle_specific)
-               *handle_specific = search_data.handle_specific;
-       return search_data.handle;
-}
-
 static gboolean
 mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data)
 {
@@ -876,7 +825,8 @@ gboolean mono_w32handle_ops_isowned (gpointer handle)
        }
 }
 
-guint32 mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted)
+MonoW32HandleWaitRet
+mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted)
 {
        MonoW32HandleBase *handle_data;
        MonoW32HandleType type;
@@ -1182,30 +1132,7 @@ mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable)
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p has special wait",
                        __func__, handle);
 
-               switch (mono_w32handle_ops_specialwait (handle, timeout, alertable ? &alerted : NULL)) {
-               case WAIT_OBJECT_0:
-                       ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
-                       break;
-               case WAIT_ABANDONED_0:
-                       ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0;
-                       break;
-               case WAIT_IO_COMPLETION:
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-                       break;
-               case WAIT_TIMEOUT:
-                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
-                       break;
-               case WAIT_FAILED:
-                       ret = MONO_W32HANDLE_WAIT_RET_FAILED;
-                       break;
-               default:
-                       g_assert_not_reached ();
-               }
-
-               if (alerted)
-                       ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
-
-               return ret;
+               return mono_w32handle_ops_specialwait (handle, timeout, alertable ? &alerted : NULL);
        }
 
        if (!mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_WAIT)) {
index 92cf87ba1194f58adf7d34e82eb3980902246cef..b67ada79afc1620be0dd42275f6219fa509a009a 100644 (file)
@@ -29,6 +29,14 @@ typedef enum {
        MONO_W32HANDLE_COUNT
 } MonoW32HandleType;
 
+typedef enum {
+       MONO_W32HANDLE_WAIT_RET_SUCCESS_0   =  0,
+       MONO_W32HANDLE_WAIT_RET_ABANDONED_0 =  MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
+       MONO_W32HANDLE_WAIT_RET_ALERTED     = -1,
+       MONO_W32HANDLE_WAIT_RET_TIMEOUT     = -2,
+       MONO_W32HANDLE_WAIT_RET_FAILED      = -3,
+} MonoW32HandleWaitRet;
+
 typedef struct 
 {
        void (*close)(gpointer handle, gpointer data);
@@ -55,7 +63,7 @@ typedef struct
         * instead of using the normal handle signal mechanism.
         * Returns the WaitForSingleObject return code.
         */
-       guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean *alerted);
+       MonoW32HandleWaitRet (*special_wait)(gpointer handle, guint32 timeout, gboolean *alerted);
 
        /* Called by WaitForSingleObject and WaitForMultipleObjects,
         * if the handle in question needs some preprocessing before the
@@ -103,9 +111,6 @@ mono_w32handle_get_type (gpointer handle);
 gboolean
 mono_w32handle_lookup (gpointer handle, MonoW32HandleType type, gpointer *handle_specific);
 
-gpointer
-mono_w32handle_search (MonoW32HandleType type, gboolean (*check)(gpointer, gpointer), gpointer user_data, gpointer *handle_specific, gboolean search_shared);
-
 void
 mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data);
 
@@ -136,7 +141,7 @@ mono_w32handle_ops_own (gpointer handle, guint32 *statuscode);
 gboolean
 mono_w32handle_ops_isowned (gpointer handle);
 
-guint32
+MonoW32HandleWaitRet
 mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean *alerted);
 
 void
@@ -166,14 +171,6 @@ mono_w32handle_trylock_handle (gpointer handle);
 int
 mono_w32handle_unlock_handle (gpointer handle);
 
-typedef enum {
-       MONO_W32HANDLE_WAIT_RET_SUCCESS_0   =  0,
-       MONO_W32HANDLE_WAIT_RET_ABANDONED_0 =  MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
-       MONO_W32HANDLE_WAIT_RET_ALERTED     = -1,
-       MONO_W32HANDLE_WAIT_RET_TIMEOUT     = -2,
-       MONO_W32HANDLE_WAIT_RET_FAILED      = -3,
-} MonoW32HandleWaitRet;
-
 MonoW32HandleWaitRet
 mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable);
 
index f4ae2a5b09f4bde87a3fad24f1595e422cccd2c1..82663cacb221dcee14986ecf82b56625595eab8e 100644 (file)
@@ -93,18 +93,6 @@ static char *mono_environ[1] = { NULL };
 extern char **environ;
 #endif
 
-/*
- * Handles > _WAPI_PROCESS_UNHANDLED are pseudo handles which represent processes
- * not started by the runtime.
- */
-/* This marks a system process that we don't have a handle on */
-/* FIXME: Cope with PIDs > sizeof guint */
-#define _WAPI_PROCESS_UNHANDLED (1 << (8*sizeof(pid_t)-1))
-
-#define WAPI_IS_PSEUDO_PROCESS_HANDLE(handle) ((GPOINTER_TO_UINT(handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED)
-#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid))
-#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED)
-
 typedef enum {
        STARTF_USESHOWWINDOW=0x001,
        STARTF_USESIZE=0x002,
@@ -157,6 +145,7 @@ struct _MonoProcess {
 /* MonoW32HandleProcess is a structure containing all the required information for process handling. */
 typedef struct {
        pid_t id;
+       gboolean child;
        guint32 exitstatus;
        gpointer main_thread;
        WapiFileTime create_time;
@@ -174,9 +163,9 @@ static mono_lazy_init_t process_sig_chld_once = MONO_LAZY_INIT_STATUS_NOT_INITIA
 
 static gchar *cli_launcher;
 
-/* The signal-safe logic to use mono_processes goes like this:
+/* The signal-safe logic to use processes goes like this:
  * - The list must be safe to traverse for the signal handler at all times.
- *   It's safe to: prepend an entry (which is a single store to 'mono_processes'),
+ *   It's safe to: prepend an entry (which is a single store to 'processes'),
  *   unlink an entry (assuming the unlinked entry isn't freed and doesn't
  *   change its 'next' pointer so that it can still be traversed).
  * When cleaning up we first unlink an entry, then we verify that
@@ -186,9 +175,8 @@ static gchar *cli_launcher;
  * We also need to lock when adding and cleaning up so that those two
  * operations don't mess with eachother. (This lock is not used in the
  * signal handler) */
-static MonoProcess *mono_processes;
-static mono_mutex_t mono_processes_mutex;
-static volatile gint32 mono_processes_cleaning_up;
+static MonoProcess *processes;
+static mono_mutex_t processes_mutex;
 
 static gpointer current_process;
 
@@ -197,6 +185,33 @@ static const gunichar2 *utf16_space = utf16_space_bytes;
 static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 };
 static const gunichar2 *utf16_quote = utf16_quote_bytes;
 
+/* Check if a pid is valid - i.e. if a process exists with this pid. */
+static gboolean
+process_is_alive (pid_t pid)
+{
+#if defined(HOST_WATCHOS)
+       return TRUE; // TODO: Rewrite using sysctl
+#elif defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
+       if (pid == 0)
+               return FALSE;
+       if (kill (pid, 0) == 0)
+               return TRUE;
+       if (errno == EPERM)
+               return TRUE;
+       return FALSE;
+#elif defined(__HAIKU__)
+       team_info teamInfo;
+       if (get_team_info ((team_id)pid, &teamInfo) == B_OK)
+               return TRUE;
+       return FALSE;
+#else
+       gchar *dir = g_strdup_printf ("/proc/%d", pid);
+       gboolean result = access (dir, F_OK) == 0;
+       g_free (dir);
+       return result;
+#endif
+}
+
 static void
 process_details (gpointer data)
 {
@@ -217,7 +232,7 @@ process_typesize (void)
        return sizeof (MonoW32HandleProcess);
 }
 
-static guint32
+static MonoW32HandleWaitRet
 process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
 {
        MonoW32HandleProcess *process_handle;
@@ -227,10 +242,6 @@ process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
        MonoProcess *mp;
        gboolean res;
 
-       /* FIXME: We can now easily wait on processes that aren't our own children,
-        * but WaitFor*Object won't call us for pseudo handles. */
-       g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED);
-
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u)", __func__, handle, timeout);
 
        if (alerted)
@@ -239,49 +250,58 @@ process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
                g_warning ("%s: error looking up process handle %p", __func__, handle);
-               return WAIT_FAILED;
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
        }
 
        if (process_handle->exited) {
                /* We've already done this one */
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Process already exited", __func__, handle, timeout);
-               return WAIT_OBJECT_0;
+               return MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
        }
 
        pid = process_handle->id;
 
+       if (pid == mono_process_current_pid ()) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on current process", __func__, handle, timeout);
+               return MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+       }
+
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): PID: %d", __func__, handle, timeout, pid);
 
-       /* We don't need to lock mono_processes here, the entry
+       /* We don't need to lock processes here, the entry
         * has a handle_count > 0 which means it will not be freed. */
        mp = process_handle->mono_process;
        if (!mp) {
                pid_t res;
 
-               if (pid == mono_process_current_pid ()) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on current process", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-
                /* This path is used when calling Process.HasExited, so
                 * it is only used to poll the state of the process, not
                 * to actually wait on it to exit */
                g_assert (timeout == 0);
 
+               /* We alway create a MonoProcess for a child process */
+               g_assert (!process_handle->child);
+
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on non-child process", __func__, handle, timeout);
 
                res = waitpid (pid, &status, WNOHANG);
-               if (res == 0) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_TIMEOUT", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
-               }
-               if (res > 0) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process waited successfully", __func__, handle, timeout);
-                       return WAIT_OBJECT_0;
+               if (res != -1)
+                       g_error ("%s: a process handle without a mono_process is not a child process", __func__);
+
+               if (errno == ECHILD) {
+                       if (!process_is_alive (pid)) {
+                               /* assume the process had exited */
+                               process_handle->exited = TRUE;
+                               process_handle->exitstatus = -1;
+                               mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+                       }
+
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process waited successfully (2)", __func__, handle, timeout);
+                       return MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
                }
 
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process WAIT_FAILED, error : %s (%d))", __func__, handle, timeout, g_strerror (errno), errno);
-               return WAIT_FAILED;
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): non-child process wait failed, error : %s (%d))", __func__, handle, timeout, g_strerror (errno), errno);
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
        }
 
        start = mono_msec_ticks ();
@@ -305,27 +325,27 @@ process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
                }
 
                if (ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): wait timeout (timeout = 0)", __func__, handle, timeout);
+                       return MONO_W32HANDLE_WAIT_RET_TIMEOUT;
                }
 
                now = mono_msec_ticks ();
                if (now - start >= timeout) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout);
-                       return WAIT_TIMEOUT;
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): wait timeout", __func__, handle, timeout);
+                       return MONO_W32HANDLE_WAIT_RET_TIMEOUT;
                }
 
                if (alerted && ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): wait alerted", __func__, handle, timeout);
                        *alerted = TRUE;
-                       return WAIT_IO_COMPLETION;
+                       return MONO_W32HANDLE_WAIT_RET_ALERTED;
                }
        }
 
        /* Process must have exited */
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Waited successfully", __func__, handle, timeout);
 
-       status = mp ? mp->status : 0;
+       status = mp->status;
        if (WIFSIGNALED (status))
                process_handle->exitstatus = 128 + WTERMSIG (status);
        else
@@ -339,12 +359,13 @@ process_wait (gpointer handle, guint32 timeout, gboolean *alerted)
 
        mono_w32handle_set_signal_state (handle, TRUE, TRUE);
 
-       return WAIT_OBJECT_0;
+       return MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
 }
 
 static void
 processes_cleanup (void)
 {
+       static gint32 cleaning_up;
        MonoProcess *mp;
        MonoProcess *prev = NULL;
        GSList *finished = NULL;
@@ -354,31 +375,31 @@ processes_cleanup (void)
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s", __func__);
 
        /* Ensure we're not in here in multiple threads at once, nor recursive. */
-       if (InterlockedCompareExchange (&mono_processes_cleaning_up, 1, 0) != 0)
+       if (InterlockedCompareExchange (&cleaning_up, 1, 0) != 0)
                return;
 
-       for (mp = mono_processes; mp; mp = mp->next) {
+       for (mp = processes; mp; mp = mp->next) {
                if (mp->pid == 0 && mp->handle) {
                        /* This process has exited and we need to remove the artifical ref
                         * on the handle */
-                       mono_os_mutex_lock (&mono_processes_mutex);
+                       mono_os_mutex_lock (&processes_mutex);
                        unref_handle = mp->handle;
                        mp->handle = NULL;
-                       mono_os_mutex_unlock (&mono_processes_mutex);
+                       mono_os_mutex_unlock (&processes_mutex);
                        if (unref_handle)
                                mono_w32handle_unref (unref_handle);
                }
        }
 
        /*
-        * Remove processes which exited from the mono_processes list.
+        * Remove processes which exited from the processes list.
         * We need to synchronize with the sigchld handler here, which runs
-        * asynchronously. The handler requires that the mono_processes list
+        * asynchronously. The handler requires that the processes list
         * remain valid.
         */
-       mono_os_mutex_lock (&mono_processes_mutex);
+       mono_os_mutex_lock (&processes_mutex);
 
-       mp = mono_processes;
+       mp = processes;
        while (mp) {
                if (mp->handle_count == 0 && mp->freeable) {
                        /*
@@ -386,8 +407,8 @@ processes_cleanup (void)
                         * This code can run parallel with the sigchld handler, but the
                         * modifications it makes are safe.
                         */
-                       if (mp == mono_processes)
-                               mono_processes = mp->next;
+                       if (mp == processes)
+                               processes = mp->next;
                        else
                                prev->next = mp->next;
                        finished = g_slist_prepend (finished, mp);
@@ -403,7 +424,7 @@ processes_cleanup (void)
 
        for (l = finished; l; l = l->next) {
                /*
-                * All the entries in the finished list are unlinked from mono_processes, and
+                * All the entries in the finished list are unlinked from processes, and
                 * they have the 'finished' flag set, which means the sigchld handler is done
                 * accessing them.
                 */
@@ -413,11 +434,11 @@ processes_cleanup (void)
        }
        g_slist_free (finished);
 
-       mono_os_mutex_unlock (&mono_processes_mutex);
+       mono_os_mutex_unlock (&processes_mutex);
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s done", __func__);
 
-       InterlockedDecrement (&mono_processes_cleaning_up);
+       InterlockedExchange (&cleaning_up, 0);
 }
 
 static void
@@ -495,7 +516,7 @@ mono_w32process_init (void)
        current_process = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
        g_assert (current_process);
 
-       mono_os_mutex_init (&mono_processes_mutex);
+       mono_os_mutex_init (&processes_mutex);
 }
 
 void
@@ -504,31 +525,6 @@ mono_w32process_cleanup (void)
        g_free (cli_launcher);
 }
 
-/* Check if a pid is valid - i.e. if a process exists with this pid. */
-static gboolean
-is_pid_valid (pid_t pid)
-{
-       gboolean result = FALSE;
-
-#if defined(HOST_WATCHOS)
-       result = TRUE; // TODO: Rewrite using sysctl
-#elif defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__FreeBSD__)
-       if (((kill(pid, 0) == 0) || (errno == EPERM)) && pid != 0)
-               result = TRUE;
-#elif defined(__HAIKU__)
-       team_info teamInfo;
-       if (get_team_info ((team_id)pid, &teamInfo) == B_OK)
-               result = TRUE;
-#else
-       char *dir = g_strdup_printf ("/proc/%d", pid);
-       if (!access (dir, F_OK))
-               result = TRUE;
-       g_free (dir);
-#endif
-
-       return result;
-}
-
 static int
 len16 (const gunichar2 *str)
 {
@@ -579,11 +575,6 @@ mono_w32process_get_pid (gpointer handle)
        MonoW32HandleProcess *process_handle;
        gboolean res;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
-               /* This is a pseudo handle */
-               return WAPI_HANDLE_TO_PID (handle);
-       }
-
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
                SetLastError (ERROR_INVALID_HANDLE);
@@ -593,58 +584,84 @@ mono_w32process_get_pid (gpointer handle)
        return process_handle->id;
 }
 
+typedef struct {
+       guint32 pid;
+       gpointer handle;
+} GetProcessForeachData;
+
 static gboolean
-process_open_compare (gpointer handle, gpointer user_data)
+get_process_foreach_callback (gpointer handle, gpointer handle_specific, gpointer user_data)
 {
-       gboolean res;
+       GetProcessForeachData *foreach_data;
        MonoW32HandleProcess *process_handle;
-       pid_t wanted_pid, checking_pid;
+       pid_t pid;
 
-       g_assert (!WAPI_IS_PSEUDO_PROCESS_HANDLE (handle));
+       foreach_data = (GetProcessForeachData*) user_data;
 
-       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-       if (!res)
-               g_error ("%s: unknown process handle %p", __func__, handle);
+       if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_PROCESS)
+               return FALSE;
+
+       process_handle = (MonoW32HandleProcess*) handle_specific;
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking at process %d", __func__, process_handle->id);
 
-       checking_pid = process_handle->id;
-       if (checking_pid == 0)
+       pid = process_handle->id;
+       if (pid == 0)
                return FALSE;
 
-       wanted_pid = GPOINTER_TO_UINT (user_data);
-
        /* It's possible to have more than one process handle with the
         * same pid, but only the one running process can be
-        * unsignalled.
-        * If the handle is blown away in the window between
-        * returning TRUE here and mono_w32handle_search pinging
-        * the timestamp, the search will continue. */
-       return checking_pid == wanted_pid && !mono_w32handle_issignalled (handle);
+        * unsignalled. */
+       if (foreach_data->pid != pid)
+               return FALSE;
+       if (mono_w32handle_issignalled (handle))
+               return FALSE;
+
+       mono_w32handle_ref (handle);
+       foreach_data->handle = handle;
+       return TRUE;
 }
 
 HANDLE
 ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
 {
+       GetProcessForeachData foreach_data;
        gpointer handle;
 
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking for process %d", __func__, pid);
 
-       handle = mono_w32handle_search (MONO_W32HANDLE_PROCESS, process_open_compare, GUINT_TO_POINTER (pid), NULL, TRUE);
+       memset (&foreach_data, 0, sizeof (foreach_data));
+       foreach_data.pid = pid;
+       mono_w32handle_foreach (get_process_foreach_callback, &foreach_data);
+       handle = foreach_data.handle;
        if (handle) {
-               /* mono_w32handle_search () already added a ref */
+               /* get_process_foreach_callback already added a ref */
                return handle;
        }
 
-       if (is_pid_valid (pid)) {
-               /* Return a pseudo handle for processes we don't have handles for */
-               return WAPI_PID_TO_HANDLE (pid);
-       } else {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find pid %d", __func__, pid);
+       if (process_is_alive (pid)) {
+               /* non-child process */
+               MonoW32HandleProcess process_handle;
 
-               SetLastError (ERROR_PROC_NOT_FOUND);
-               return NULL;
+               memset (&process_handle, 0, sizeof (process_handle));
+               process_handle.id = pid;
+               process_handle.proc_name = mono_w32process_get_name (pid);
+
+               handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+               if (handle == INVALID_HANDLE_VALUE) {
+                       g_warning ("%s: error creating process handle", __func__);
+
+                       SetLastError (ERROR_OUTOFMEMORY);
+                       return NULL;
+               }
+
+               return handle;
        }
+
+       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find pid %d", __func__, pid);
+
+       SetLastError (ERROR_PROC_NOT_FOUND);
+       return NULL;
 }
 
 static gboolean
@@ -716,20 +733,15 @@ mono_w32process_try_get_modules (gpointer process, gpointer *modules, guint32 si
        if (size < sizeof(gpointer))
                return FALSE;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               pid = WAPI_HANDLE_TO_PID (process);
-               proc_name = mono_w32process_get_name (pid);
-       } else {
-               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-                       return FALSE;
-               }
-
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
+       res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+               return FALSE;
        }
 
+       pid = process_handle->id;
+       proc_name = g_strdup (process_handle->proc_name);
+
        if (!proc_name) {
                modules[0] = NULL;
                *needed = sizeof(gpointer);
@@ -844,21 +856,15 @@ mono_w32process_module_get_name (gpointer process, gpointer module, gunichar2 *b
        if (basename == NULL || size == 0)
                return 0;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-               proc_name = mono_w32process_get_name (pid);
-       } else {
-               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-                       return 0;
-               }
-
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
+       res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+               return 0;
        }
 
+       pid = process_handle->id;
+       proc_name = g_strdup (process_handle->proc_name);
+
        mods = mono_w32process_get_modules (pid);
        if (!mods) {
                g_free (proc_name);
@@ -948,20 +954,15 @@ mono_w32process_module_get_information (gpointer process, gpointer module, WapiM
        if (modinfo == NULL || size < sizeof (WapiModuleInfo))
                return FALSE;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) {
-               pid = (pid_t)WAPI_HANDLE_TO_PID (process);
-               proc_name = mono_w32process_get_name (pid);
-       } else {
-               res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
-                       return FALSE;
-               }
-
-               pid = process_handle->id;
-               proc_name = g_strdup (process_handle->proc_name);
+       res = mono_w32handle_lookup (process, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, process);
+               return FALSE;
        }
 
+       pid = process_handle->id;
+       proc_name = g_strdup (process_handle->proc_name);
+
        mods = mono_w32process_get_modules (pid);
        if (!mods) {
                g_free (proc_name);
@@ -1026,18 +1027,17 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi
                /*
                 * This can run concurrently with the code in the rest of this module.
                 */
-               for (p = mono_processes; p; p = p->next) {
-                       if (p->pid == pid) {
-                               break;
-                       }
-               }
-               if (p) {
+               for (p = processes; p; p = p->next) {
+                       if (p->pid != pid)
+                               continue;
+
                        p->pid = 0; /* this pid doesn't exist anymore, clear it */
                        p->status = status;
                        mono_os_sem_post (&p->exit_sem);
                        mono_memory_barrier ();
                        /* Mark this as freeable, the pointer becomes invalid afterwards */
                        p->freeable = TRUE;
+                       break;
                }
        } while (1);
 }
@@ -1223,15 +1223,12 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new
        guint32 i, env_count = 0;
        gboolean ret = FALSE;
        gpointer handle = NULL;
-       MonoW32HandleProcess process_handle = {0}, *process_handle_data;
        GError *gerr = NULL;
        int in_fd, out_fd, err_fd;
        pid_t pid = 0;
        int startup_pipe [2] = {-1, -1};
        int dummy;
        MonoProcess *mono_process;
-       gboolean fork_failed = FALSE;
-       gboolean res;
 
 #if HAVE_SIGACTION
        mono_lazy_initialize (&process_sig_chld_once, process_add_sigchld_handler);
@@ -1529,19 +1526,6 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new
                err_fd = GPOINTER_TO_UINT (GetStdHandle (STD_ERROR_HANDLE));
        }
 
-       process_handle.proc_name = g_strdup (prog);
-
-       process_set_defaults (&process_handle);
-
-       handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
-       if (handle == INVALID_HANDLE_VALUE) {
-               g_warning ("%s: error creating process handle", __func__);
-
-               ret = FALSE;
-               SetLastError (ERROR_OUTOFMEMORY);
-               goto free_strings;
-       }
-
        /* new_environ is a block of NULL-terminated strings, which
         * is itself NULL-terminated. Of course, passing an array of
         * string pointers would have made things too easy :-(
@@ -1598,7 +1582,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new
        }
 
        /* Create a pipe to make sure the child doesn't exit before
-        * we can add the process to the linked list of mono_processes */
+        * we can add the process to the linked list of processes */
        if (pipe (startup_pipe) == -1) {
                /* Could not create the pipe to synchroniz process startup. We'll just not synchronize.
                 * This is just for a very hard to hit race condition in the first place */
@@ -1606,11 +1590,14 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: new process startup not synchronized. We may not notice if the newly created process exits immediately.", __func__);
        }
 
+#if HAVE_SIGACTION
+       /* FIXME: block SIGCHLD */
+#endif
+
        switch (pid = fork ()) {
        case -1: /* Error */ {
                SetLastError (ERROR_OUTOFMEMORY);
                ret = FALSE;
-               fork_failed = TRUE;
                break;
        }
        case 0: /* Child */ {
@@ -1658,47 +1645,60 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline, gpointer new
                break;
        }
        default: /* Parent */ {
-               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle_data);
-               if (!res) {
-                       g_warning ("%s: error looking up process handle %p", __func__, handle);
-                       mono_w32handle_unref (handle);
-               } else {
-                       process_handle_data->id = pid;
+               MonoW32HandleProcess process_handle;
 
-                       /* Add our mono_process into the linked list of mono_processes */
-                       mono_process = (MonoProcess *) g_malloc0 (sizeof (MonoProcess));
-                       mono_process->pid = pid;
-                       mono_process->handle_count = 1;
-                       mono_os_sem_init (&mono_process->exit_sem, 0);
+               memset (&process_handle, 0, sizeof (process_handle));
+               process_handle.id = pid;
+               process_handle.child = TRUE;
+               process_handle.proc_name = g_strdup (prog);
+               process_set_defaults (&process_handle);
 
-                       /* Keep the process handle artificially alive until the process
-                        * exits so that the information in the handle isn't lost. */
-                       mono_w32handle_ref (handle);
-                       mono_process->handle = handle;
+               /* Add our mono_process into the linked list of processes */
+               mono_process = (MonoProcess *) g_malloc0 (sizeof (MonoProcess));
+               mono_process->pid = pid;
+               mono_process->handle_count = 1;
+               mono_os_sem_init (&mono_process->exit_sem, 0);
 
-                       process_handle_data->mono_process = mono_process;
+               process_handle.mono_process = mono_process;
 
-                       mono_os_mutex_lock (&mono_processes_mutex);
-                       mono_process->next = mono_processes;
-                       mono_processes = mono_process;
-                       mono_os_mutex_unlock (&mono_processes_mutex);
+               handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+               if (handle == INVALID_HANDLE_VALUE) {
+                       g_warning ("%s: error creating process handle", __func__);
 
-                       if (process_info != NULL) {
-                               process_info->process_handle = handle;
-                               process_info->pid = pid;
+                       mono_os_sem_destroy (&mono_process->exit_sem);
+                       g_free (mono_process);
 
-                               /* FIXME: we might need to handle the thread info some day */
-                               process_info->thread_handle = INVALID_HANDLE_VALUE;
-                               process_info->tid = 0;
-                       }
+                       SetLastError (ERROR_OUTOFMEMORY);
+                       ret = FALSE;
+                       break;
+               }
+
+               /* Keep the process handle artificially alive until the process
+                * exits so that the information in the handle isn't lost. */
+               mono_w32handle_ref (handle);
+               mono_process->handle = handle;
+
+               mono_os_mutex_lock (&processes_mutex);
+               mono_process->next = processes;
+               processes = mono_process;
+               mono_os_mutex_unlock (&processes_mutex);
+
+               if (process_info != NULL) {
+                       process_info->process_handle = handle;
+                       process_info->pid = pid;
+
+                       /* FIXME: we might need to handle the thread info some day */
+                       process_info->thread_handle = INVALID_HANDLE_VALUE;
+                       process_info->tid = 0;
                }
 
                break;
        }
        }
 
-       if (fork_failed)
-               mono_w32handle_unref (handle);
+#if HAVE_SIGACTION
+       /* FIXME: unblock SIGCHLD */
+#endif
 
        if (startup_pipe [1] != -1) {
                /* Write 1 byte, doesn't matter what */
@@ -2029,25 +2029,11 @@ MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
 {
        MonoW32HandleProcess *process_handle;
-       guint32 pid;
        gboolean res;
 
        if (!exitcode)
                return FALSE;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
-               pid = WAPI_HANDLE_TO_PID (handle);
-               /* This is a pseudo handle, so we don't know what the exit
-                * code was, but we can check whether it's alive or not */
-               if (is_pid_valid (pid)) {
-                       *exitcode = STILL_ACTIVE;
-                       return TRUE;
-               } else {
-                       *exitcode = -1;
-                       return TRUE;
-               }
-       }
-
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
@@ -2072,8 +2058,6 @@ ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gin
 MonoBoolean
 ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
 {
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
-               return TRUE;
        return CloseHandle (handle);
 }
 
@@ -2084,23 +2068,17 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
        MonoW32HandleProcess *process_handle;
        int ret;
        pid_t pid;
+       gboolean res;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
-       } else {
-               gboolean res;
-
-               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return FALSE;
-               }
-
-               pid = process_handle->id;
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               SetLastError (ERROR_INVALID_HANDLE);
+               return FALSE;
        }
 
+       pid = process_handle->id;
+
        ret = kill (pid, exitcode == -1 ? SIGKILL : SIGTERM);
        if (ret == 0)
                return TRUE;
@@ -2127,15 +2105,15 @@ ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handl
        if (!min || !max)
                return FALSE;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
-               return FALSE;
-
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
                return FALSE;
        }
 
+       if (!process_handle->child)
+               return FALSE;
+
        *min = process_handle->min_working_set;
        *max = process_handle->max_working_set;
        return TRUE;
@@ -2147,15 +2125,15 @@ ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handl
        MonoW32HandleProcess *process_handle;
        gboolean res;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle))
-               return FALSE;
-
        res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
        if (!res) {
                mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
                return FALSE;
        }
 
+       if (!process_handle->child)
+               return FALSE;
+
        process_handle->min_working_set = min;
        process_handle->max_working_set = max;
        return TRUE;
@@ -2168,22 +2146,16 @@ ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
        MonoW32HandleProcess *process_handle;
        gint ret;
        pid_t pid;
+       gboolean res;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
-       } else {
-               gboolean res;
-
-               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return 0;
-               }
-
-               pid = process_handle->id;
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return 0;
        }
 
+       pid = process_handle->id;
+
        errno = 0;
        ret = getpriority (PRIO_PROCESS, pid);
        if (ret == -1 && errno != 0) {
@@ -2229,22 +2201,16 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
        int ret;
        int prio;
        pid_t pid;
+       gboolean res;
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
-               /* This is a pseudo handle */
-               pid = (pid_t)WAPI_HANDLE_TO_PID (handle);
-       } else {
-               gboolean res;
-
-               res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-               if (!res) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return FALSE;
-               }
-
-               pid = process_handle->id;
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               SetLastError (ERROR_INVALID_HANDLE);
+               return FALSE;
        }
 
+       pid = process_handle->id;
+
        switch (priorityClass) {
        case MONO_W32PROCESS_PRIORITY_CLASS_IDLE:
                prio = 19;
@@ -2327,10 +2293,16 @@ ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64
        memset (kernel_processtime, 0, sizeof (ProcessTime));
        memset (user_processtime, 0, sizeof (ProcessTime));
 
-       if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) {
+       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
+       if (!res) {
+               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
+               return FALSE;
+       }
+
+       if (!process_handle->child) {
                gint64 start_ticks, user_ticks, kernel_ticks;
 
-               mono_process_get_times (GINT_TO_POINTER (WAPI_HANDLE_TO_PID (handle)),
+               mono_process_get_times (GINT_TO_POINTER (process_handle->id),
                        &start_ticks, &user_ticks, &kernel_ticks);
 
                ticks_to_processtime (start_ticks, creation_processtime);
@@ -2339,12 +2311,6 @@ ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64
                return TRUE;
        }
 
-       res = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS, (gpointer*) &process_handle);
-       if (!res) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't find process %p", __func__, handle);
-               return FALSE;
-       }
-
        wapifiletime_to_processtime (process_handle->create_time, creation_processtime);
 
        /* A process handle is only signalled if the process has
index ce15318d225a66a654d0dc3fb2226743bfe236ea..b581dc35e4a9c19048a55e459b1e2ef039edcfb9 100644 (file)
@@ -4,6 +4,7 @@
  * Author:
  *   Dietmar Maurer (dietmar@ximian.com)
  *   Zoltan Varga (vargaz@gmail.com)
+ *   Johan Lorensson (lateralusx.github@gmail.com)
  *
  * (C) 2002 Ximian, Inc.
  * Copyright 2003-2011 Novell, Inc 
 
 #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
 
+// Use MSVC toolchain, Clang for MSVC using MSVC codegen and linker, when compiling for AMD64
+// targeting WIN32 platforms running AOT compiler on WIN32 platform with VS installation.
+#if defined(TARGET_AMD64) && defined(TARGET_WIN32) && defined(HOST_WIN32) && defined(_MSC_VER)
+#define TARGET_X86_64_WIN32_MSVC
+#endif
+
+#if defined(TARGET_X86_64_WIN32_MSVC)
+#define TARGET_WIN32_MSVC
+#endif
+
 #if defined(__linux__) || defined(__native_client_codegen__)
 #define RODATA_SECT ".rodata"
 #elif defined(TARGET_MACH)
 #define RODATA_SECT ".section __TEXT, __const"
+#elif defined(TARGET_WIN32_MSVC)
+#define RODATA_SECT ".rdata"
 #else
 #define RODATA_SECT ".text"
 #endif
@@ -605,11 +618,29 @@ emit_global_inner (MonoAotCompile *acfg, const char *name, gboolean func)
 
 #endif
 
+static inline gboolean
+link_shared_library (MonoAotCompile *acfg)
+{
+       return !acfg->aot_opts.static_link && !acfg->aot_opts.asm_only;
+}
+
+static inline gboolean
+add_to_global_symbol_table (MonoAotCompile *acfg)
+{
+#ifdef TARGET_WIN32_MSVC
+       return acfg->aot_opts.no_dlsym || link_shared_library (acfg);
+#else
+       return acfg->aot_opts.no_dlsym;
+#endif
+}
+
 static void
 emit_global (MonoAotCompile *acfg, const char *name, gboolean func)
 {
-       if (acfg->aot_opts.no_dlsym) {
+       if (add_to_global_symbol_table (acfg))
                g_ptr_array_add (acfg->globals, g_strdup (name));
+
+       if (acfg->aot_opts.no_dlsym) {
                mono_img_writer_emit_local_symbol (acfg->w, name, NULL, func);
        } else {
                emit_global_inner (acfg, name, func);
@@ -814,6 +845,10 @@ emit_code_bytes (MonoAotCompile *acfg, const guint8* buf, int size)
 #define EMIT_DWARF_INFO 1
 #endif
 
+#ifdef TARGET_WIN32_MSVC
+#undef EMIT_DWARF_INFO
+#endif
+
 #if defined(TARGET_ARM)
 #define AOT_FUNC_ALIGNMENT 4
 #else
@@ -828,7 +863,9 @@ emit_code_bytes (MonoAotCompile *acfg, const guint8* buf, int size)
 #define PPC_LDX_OP "lwzx"
 #endif
 
-#ifdef TARGET_AMD64
+#ifdef TARGET_X86_64_WIN32_MSVC
+#define AOT_TARGET_STR "AMD64 (WIN32) (MSVC codegen)"
+#elif TARGET_AMD64
 #define AOT_TARGET_STR "AMD64"
 #endif
 
@@ -2488,7 +2525,8 @@ mono_get_field_token (MonoClassField *field)
        MonoClass *klass = field->parent;
        int i;
 
-       for (i = 0; i < klass->field.count; ++i) {
+       int fcount = mono_class_get_field_count (klass);
+       for (i = 0; i < fcount; ++i) {
                if (field == &klass->fields [i])
                        return MONO_TOKEN_FIELD_DEF | (mono_class_get_first_field_idx (klass) + 1 + i);
        }
@@ -7793,7 +7831,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
        InterlockedIncrement (&acfg->stats.ccount);
 }
  
-static gsize WINAPI
+static mono_thread_start_return_t WINAPI
 compile_thread_main (gpointer user_data)
 {
        MonoDomain *domain = ((MonoDomain **)user_data) [0];
@@ -8194,18 +8232,18 @@ execute_system (const char * command)
 {
        int status = 0;
 
-#if _WIN32
+#if HOST_WIN32
        // We need an extra set of quotes around the whole command to properly handle commands 
        // with spaces since internally the command is called through "cmd /c.
-       command = g_strdup_printf ("\"%s\"", command);
+       char * quoted_command = g_strdup_printf ("\"%s\"", command);
 
-       int size =  MultiByteToWideChar (CP_UTF8, 0 , command , -1, NULL , 0);
+       int size =  MultiByteToWideChar (CP_UTF8, 0 , quoted_command , -1, NULL , 0);
        wchar_t* wstr = g_malloc (sizeof (wchar_t) * size);
-       MultiByteToWideChar (CP_UTF8, 0, command, -1, wstr , size);
+       MultiByteToWideChar (CP_UTF8, 0, quoted_command, -1, wstr , size);
        status = _wsystem (wstr);
        g_free (wstr);
 
-       g_free (command);
+       g_free (quoted_command);
 #elif defined (HAVE_SYSTEM)
        status = system (command);
 #else
@@ -8458,7 +8496,8 @@ emit_code (MonoAotCompile *acfg)
        emit_section_change (acfg, ".text", 1);
        emit_alignment_code (acfg, 8);
        emit_info_symbol (acfg, symbol);
-       emit_local_symbol (acfg, symbol, "method_addresses_end", TRUE);
+       if (acfg->aot_opts.write_symbols)
+               emit_local_symbol (acfg, symbol, "method_addresses_end", TRUE);
        emit_unset_mode (acfg);
        if (acfg->need_no_dead_strip)
                fprintf (acfg->fp, "    .no_dead_strip %s\n", symbol);
@@ -9253,7 +9292,8 @@ emit_got (MonoAotCompile *acfg)
 #else
        emit_section_change (acfg, ".bss", 0);
        emit_alignment (acfg, 8);
-       emit_local_symbol (acfg, symbol, "got_end", FALSE);
+       if (acfg->aot_opts.write_symbols)
+               emit_local_symbol (acfg, symbol, "got_end", FALSE);
        emit_label (acfg, symbol);
        if (acfg->llvm)
                emit_info_symbol (acfg, "jit_got");
@@ -9270,6 +9310,53 @@ typedef struct GlobalsTableEntry {
        struct GlobalsTableEntry *next;
 } GlobalsTableEntry;
 
+#ifdef TARGET_WIN32_MSVC
+#define DLL_ENTRY_POINT "DllMain"
+
+static void
+emit_library_info (MonoAotCompile *acfg)
+{
+       // Only include for shared libraries linked directly from generated object.
+       if (link_shared_library (acfg)) {
+               char    *name = NULL;
+               char    symbol [MAX_SYMBOL_SIZE];
+
+               // Ask linker to export all global symbols.
+               emit_section_change (acfg, ".drectve", 0);
+               for (guint i = 0; i < acfg->globals->len; ++i) {
+                       name = (char *)g_ptr_array_index (acfg->globals, i);
+                       g_assert (name != NULL);
+                       sprintf_s (symbol, MAX_SYMBOL_SIZE, " /EXPORT:%s", name);
+                       emit_string (acfg, symbol);
+               }
+
+               // Emit DLLMain function, needed by MSVC linker for DLL's.
+               // NOTE, DllMain should not go into exports above.
+               emit_section_change (acfg, ".text", 0);
+               emit_global (acfg, DLL_ENTRY_POINT, TRUE);
+               emit_label (acfg, DLL_ENTRY_POINT);
+
+               // Simple implementation of DLLMain, just returning TRUE.
+               // For more information about DLLMain: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
+               fprintf (acfg->fp, "movl $1, %%eax\n");
+               fprintf (acfg->fp, "ret\n");
+
+               // Inform linker about our dll entry function.
+               emit_section_change (acfg, ".drectve", 0);
+               emit_string (acfg, "/ENTRY:" DLL_ENTRY_POINT);
+               return;
+       }
+}
+
+#else
+
+static inline void
+emit_library_info (MonoAotCompile *acfg)
+{
+       return;
+}
+#endif
+
 static void
 emit_globals (MonoAotCompile *acfg)
 {
@@ -9281,6 +9368,7 @@ emit_globals (MonoAotCompile *acfg)
 
        if (!acfg->aot_opts.static_link)
                return;
+
        if (acfg->aot_opts.llvm_only) {
                g_assert (acfg->globals->len == 0);
                return;
@@ -9852,7 +9940,9 @@ compile_asm (MonoAotCompile *acfg)
        const char *tool_prefix = acfg->aot_opts.tool_prefix ? acfg->aot_opts.tool_prefix : "";
        char *ld_flags = acfg->aot_opts.ld_flags ? acfg->aot_opts.ld_flags : g_strdup("");
 
-#if defined(TARGET_AMD64) && !defined(TARGET_MACH)
+#ifdef TARGET_WIN32_MSVC
+#define AS_OPTIONS "-c -x assembler"
+#elif defined(TARGET_AMD64) && !defined(TARGET_MACH)
 #define AS_OPTIONS "--64"
 #elif defined(TARGET_POWERPC64)
 #define AS_OPTIONS "-a64 -mppc64"
@@ -9872,10 +9962,18 @@ compile_asm (MonoAotCompile *acfg)
 #endif
 #elif defined(TARGET_OSX)
 #define AS_NAME "clang"
+#elif defined(TARGET_WIN32_MSVC)
+#define AS_NAME "clang.exe"
 #else
 #define AS_NAME "as"
 #endif
 
+#ifdef TARGET_WIN32_MSVC
+#define AS_OBJECT_FILE_SUFFIX "obj"
+#else
+#define AS_OBJECT_FILE_SUFFIX "o"
+#endif
+
 #if defined(sparc)
 #define LD_NAME "ld"
 #define LD_OPTIONS "-shared -G"
@@ -9885,6 +9983,9 @@ compile_asm (MonoAotCompile *acfg)
 #elif defined(TARGET_AMD64) && defined(TARGET_MACH)
 #define LD_NAME "clang"
 #define LD_OPTIONS "--shared"
+#elif defined(TARGET_WIN32_MSVC)
+#define LD_NAME "link.exe"
+#define LD_OPTIONS "/DLL /MACHINE:X64 /NOLOGO"
 #elif defined(TARGET_WIN32) && !defined(TARGET_ANDROID)
 #define LD_NAME "gcc"
 #define LD_OPTIONS "-shared"
@@ -9915,9 +10016,9 @@ compile_asm (MonoAotCompile *acfg)
                if (acfg->aot_opts.outfile)
                        objfile = g_strdup_printf ("%s", acfg->aot_opts.outfile);
                else
-                       objfile = g_strdup_printf ("%s.o", acfg->image->name);
+                       objfile = g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->image->name);
        } else {
-               objfile = g_strdup_printf ("%s.o", acfg->tmpfname);
+               objfile = g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname);
        }
 
 #ifdef TARGET_OSX
@@ -9974,21 +10075,26 @@ compile_asm (MonoAotCompile *acfg)
        if (acfg->aot_opts.llvm_only)
                ld_flags = g_strdup_printf ("%s %s", ld_flags, "-lstdc++");
 
-#ifdef LD_NAME
+#ifdef TARGET_WIN32_MSVC
+       g_assert (tmp_outfile_name != NULL);
+       g_assert (objfile != NULL);
+       command = g_strdup_printf ("\"%s%s\" %s %s /OUT:\"%s\" \"%s\"", tool_prefix, LD_NAME, LD_OPTIONS,
+               ld_flags, tmp_outfile_name, objfile);
+#elif defined(LD_NAME)
        command = g_strdup_printf ("%s%s %s -o %s %s %s %s", tool_prefix, LD_NAME, LD_OPTIONS,
                wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
-               wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
+               wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags);
 #else
        // Default (linux)
        if (acfg->aot_opts.tool_prefix) {
                /* Cross compiling */
                command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
                                                                   wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
-                                                                  wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
+                                                                  wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags);
        } else {
                char *args = g_strdup_printf ("%s -shared -o %s %s %s %s", LD_OPTIONS,
                                                                          wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
-                                                                         wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
+                                                                         wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags);
 
                if (acfg->llvm) {
                        command = g_strdup_printf ("clang++ %s", args);
@@ -9997,7 +10103,6 @@ compile_asm (MonoAotCompile *acfg)
                }
                g_free (args);
        }
-
 #endif
        aot_printf (acfg, "Executing the native linker: %s\n", command);
        if (execute_system (command) != 0) {
@@ -10690,6 +10795,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                acfg->gas_line_numbers = TRUE;
        }
 
+#ifdef EMIT_DWARF_INFO
        if ((!acfg->aot_opts.nodebug || acfg->aot_opts.dwarf_debug) && acfg->has_jitted_code) {
                if (acfg->aot_opts.dwarf_debug && !mono_debug_enabled ()) {
                        aot_printerrf (acfg, "The dwarf AOT option requires the --debug option.\n");
@@ -10697,6 +10803,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                }
                acfg->dwarf = mono_dwarf_writer_create (acfg->w, NULL, 0, !acfg->gas_line_numbers);
        }
+#endif /* EMIT_DWARF_INFO */
 
        if (acfg->w)
                mono_img_writer_emit_start (acfg->w);
@@ -10747,6 +10854,8 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 
        emit_file_info (acfg);
 
+       emit_library_info (acfg);
+
        if (acfg->dwarf) {
                emit_dwarf_info (acfg);
                mono_dwarf_writer_close (acfg->dwarf);
index ec40de9a8bc83cb65a81e1d54d372fc64adda781..010694bdd3206d18a1ca755d7f6f92d7614a22cd 100644 (file)
@@ -5395,7 +5395,10 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
        tls = (DebuggerTlsData *)mono_g_hash_table_lookup (thread_to_tls, thread);
        mono_loader_unlock ();
        g_assert (tls);
-       g_assert (tls->context.valid);
+       if (!tls->context.valid) {
+               DEBUG_PRINTF (1, "Received a single step request on a thread with no managed frames.");
+               return ERR_INVALID_ARGUMENT;
+       }
 
        if (tls->restore_state.valid && MONO_CONTEXT_GET_IP (&tls->context.ctx) != MONO_CONTEXT_GET_IP (&tls->restore_state.ctx)) {
                /*
index 80a579b05eb87e539e3b1c344edf636991b4c667..684d2d9a469a757f36deb86e1d0702c018b23458 100644 (file)
@@ -697,6 +697,11 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s
        }
 #else
        UCONTEXT_REG_NIP(uc) = (unsigned long)altstack_handle_and_restore;
+#if _CALL_ELF == 2
+       /* ELF v2 ABI calling convention requires to put the target address into
+       * r12 if we use the global entry point of a function. */
+       UCONTEXT_REG_Rn(uc, 12) = (unsigned long) altstack_handle_and_restore;
+#endif
 #endif
        UCONTEXT_REG_Rn(uc, 1) = (unsigned long)sp;
        UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG) = (unsigned long)(sp + 16);
@@ -739,6 +744,11 @@ setup_ucontext_return (void *uc, gpointer func)
        }
 #else
        UCONTEXT_REG_NIP(uc) = (unsigned long)func;
+#if _CALL_ELF == 2
+       /* ELF v2 ABI calling convention requires to put the target address into
+       * r12 if we use the global entry point of a function. */
+       UCONTEXT_REG_Rn(uc, 12) = (unsigned long) func;
+#endif
 #endif
 #endif
 }
index 89985dea268e77879fc27c9912f14447820ff083..fe0957fa3f2a1a750ff8405a9b7e824a1c333c1e 100644 (file)
@@ -540,7 +540,7 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea
        int i, stack_size, stack_offset, arg_offsets [5], regs_offset;
        MonoJumpInfo *ji = NULL;
        GSList *unwind_ops = NULL;
-       guint kMaxCodeSize = 128;
+       guint kMaxCodeSize = 192;
 
        start = code = mono_global_codeman_reserve (kMaxCodeSize);
 
index ab3bf8094a56e711648810e6ea8e7bfe3ea4c8dd..2e4619301d1b6ca24b81da6be81759e9fbef874b 100644 (file)
@@ -5,6 +5,7 @@
  *   Dietmar Maurer (dietmar@ximian.com)
  *   Zoltan Varga (vargaz@gmail.com)
  *   Paolo Molaro (lupus@ximian.com)
+ *   Johan Lorensson (lateralusx.github@gmail.com)
  *
  * (C) 2002 Ximian, Inc.
  */
@@ -88,6 +89,8 @@
 
 #if defined(TARGET_ASM_APPLE)
 #define AS_INT16_DIRECTIVE ".short"
+#elif defined(TARGET_ASM_GAS) && defined(TARGET_WIN32)
+#define AS_INT16_DIRECTIVE ".word"
 #elif defined(TARGET_ASM_GAS)
 #define AS_INT16_DIRECTIVE ".hword"
 #else
@@ -1735,8 +1738,45 @@ const char *get_label (const char *s)
        return s;
 }
 
+#ifdef TARGET_WIN32
+#define GLOBAL_SYMBOL_DEF_SCL 2
+#define LOCAL_SYMBOL_DEF_SCL 3
+
+static gboolean
+asm_writer_in_data_section (MonoImageWriter *acfg)
+{
+       gboolean        in_data_section = FALSE;
+       const char      *data_sections [] = {".data", ".bss", ".rdata"};
+
+       for (guchar i = 0; i < G_N_ELEMENTS (data_sections); ++i) {
+               if (strcmp (acfg->current_section, data_sections [i]) == 0) {
+                       in_data_section = TRUE;
+                       break;
+               }
+       }
+
+       return in_data_section;
+}
+
+static void
+asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean func, gboolean global)
+{
+       asm_writer_emit_unset_mode (acfg);
+
+       if (func) {
+               fprintf (acfg->fp, "\t.def %s; .scl %d; .type 32; .endef\n", name, (global == TRUE ? GLOBAL_SYMBOL_DEF_SCL : LOCAL_SYMBOL_DEF_SCL));
+       } else {
+               if (!asm_writer_in_data_section (acfg))
+                       fprintf (acfg->fp, "\t.data\n");
+       }
+
+       return;
+}
+
+#else
+
 static void
-asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean func)
+asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean func, gboolean global)
 {
        const char *stype;
 
@@ -1749,17 +1789,13 @@ asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean f
 
 #if defined(TARGET_ASM_APPLE)
 
-#elif defined(TARGET_WIN32)
-       if (func)
-               fprintf (acfg->fp, "\t.def %s; .scl 2; .type 32; .endef\n", name);
-       else
-               fprintf (acfg->fp, "\t.data\n");
 #elif defined(TARGET_ARM)
        fprintf (acfg->fp, "\t.type %s,#%s\n", name, stype);
 #else
        fprintf (acfg->fp, "\t.type %s,@%s\n", name, stype);
 #endif
 }
+#endif /* TARGET_WIN32 */
 
 static void
 asm_writer_emit_global (MonoImageWriter *acfg, const char *name, gboolean func)
@@ -1768,7 +1804,7 @@ asm_writer_emit_global (MonoImageWriter *acfg, const char *name, gboolean func)
 
        fprintf (acfg->fp, "\t.globl %s\n", name);
 
-       asm_writer_emit_symbol_type (acfg, name, func);
+       asm_writer_emit_symbol_type (acfg, name, func, TRUE);
 }
 
 static void
@@ -1780,7 +1816,7 @@ asm_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const cha
        fprintf (acfg->fp, "\t.local %s\n", name);
 #endif
 
-       asm_writer_emit_symbol_type (acfg, name, func);
+       asm_writer_emit_symbol_type (acfg, name, func, FALSE);
 }
 
 static void
index 77f8bc9578c9cea42168c5695dd3dca43d53ff6c..80044897a83e48a34caee27a8aa05d1a92e74edc 100644 (file)
@@ -151,7 +151,7 @@ bundle_save_library_initialize ()
        bundle_save_library_initialized = 1;
        char *path = g_build_filename (g_get_tmp_dir (), "mono-bundle-XXXXXX", NULL);
        bundled_dylibrary_directory = g_mkdtemp (path);
-       /* don't free path - mkdtemp modifies it in place, and bundled_dylibrary_directory is an alias of it */
+       g_free (path);
        if (bundled_dylibrary_directory == NULL)
                return;
        atexit (delete_bundled_libraries);
index e19467f8945dc90d4f2b27a41abd00b30e430501..3b4dd15c8c9acb3dc3a9bed4b689f664526ffe62 100644 (file)
@@ -1789,25 +1789,21 @@ mono_arch_flush_icache (guint8 *code, gint size)
         * icache/dcache cache line sizes, that can vary between cores on
         * big.LITTLE architectures. */
        guint64 end = (guint64) (code + size);
-       guint64 addr, ctr_el0;
-       static size_t icache_line_size = 0xffff, dcache_line_size = 0xffff;
-       size_t isize, dsize;
-
-       asm volatile ("mrs %0, ctr_el0" : "=r" (ctr_el0));
-       isize = 4 << ((ctr_el0 >> 0 ) & 0xf);
-       dsize = 4 << ((ctr_el0 >> 16) & 0xf);
-
-       /* determine the global minimum cache line size */
-       icache_line_size = isize = MIN (icache_line_size, isize);
-       dcache_line_size = dsize = MIN (dcache_line_size, dsize);
-
-       addr = (guint64) code & ~(guint64) (dsize - 1);
-       for (; addr < end; addr += dsize)
+       guint64 addr;
+       /* always go with cacheline size of 4 bytes as this code isn't perf critical
+        * anyway. Reading the cache line size from a machine register can be racy
+        * on a big.LITTLE architecture if the cores don't have the same cache line
+        * sizes. */
+       const size_t icache_line_size = 4;
+       const size_t dcache_line_size = 4;
+
+       addr = (guint64) code & ~(guint64) (dcache_line_size - 1);
+       for (; addr < end; addr += dcache_line_size)
                asm volatile("dc civac, %0" : : "r" (addr) : "memory");
        asm volatile("dsb ish" : : : "memory");
 
-       addr = (guint64) code & ~(guint64) (isize - 1);
-       for (; addr < end; addr += isize)
+       addr = (guint64) code & ~(guint64) (icache_line_size - 1);
+       for (; addr < end; addr += icache_line_size)
                asm volatile("ic ivau, %0" : : "r" (addr) : "memory");
 
        asm volatile ("dsb ish" : : : "memory");
index 07174330eb2ae3c8d85f8eb6122e605f6827a9fc..563a3a5b5de5caa4e94c8cbc673b04cb1e61ac32 100644 (file)
@@ -482,14 +482,15 @@ mono_class_get_method_generic (MonoClass *klass, MonoMethod *method)
                mono_class_setup_methods (klass);
                if (mono_class_has_failure (klass))
                        return NULL;
-               for (i = 0; i < klass->method.count; ++i) {
+               int mcount = mono_class_get_method_count (klass);
+               for (i = 0; i < mcount; ++i) {
                        m = klass->methods [i];
                        if (m == declaring)
                                break;
                        if (m->is_inflated && mono_method_get_declaring_generic_method (m) == declaring)
                                break;
                }
-               if (i >= klass->method.count)
+               if (i >= mcount)
                        return NULL;
        }
 
index 2ea49cc45689839ed2262a3a372731b8fa5a69b6..bf56b43d45ad23dd9dc30cace177d3819d6df1b0 100644 (file)
@@ -77,13 +77,8 @@ typedef struct MonoCompileArch {
 #define PPC_USES_FUNCTION_DESCRIPTOR
 #endif
 
-#ifndef __mono_ilp32__
-#define MONO_ARCH_HAVE_TLS_GET 1
-#endif
-
 #else /* must be __mono_ppc__ */
 
-#define MONO_ARCH_HAVE_TLS_GET 1
 #define MONO_ARCH_EMULATE_FCONV_TO_I8 1
 #define MONO_ARCH_EMULATE_LCONV_TO_R8 1
 #define MONO_ARCH_EMULATE_LCONV_TO_R4 1
@@ -183,7 +178,6 @@ typedef struct MonoCompileArch {
 #define PPC_LAST_FPARG_REG ppc_f13
 #define PPC_PASS_STRUCTS_BY_VALUE 1
 #define PPC_THREAD_PTR_REG ppc_r13
-#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
 #else
 #define PPC_RET_ADDR_OFFSET 4
 #define PPC_STACK_PARAM_OFFSET 8
@@ -200,6 +194,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_RETURN_CAN_USE_MULTIPLE_REGISTERS 0
 #define PPC_THREAD_PTR_REG ppc_r2
 #endif
+#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
 #define PPC_FIRST_ARG_REG ppc_r3
 #define PPC_LAST_ARG_REG ppc_r10
 #define PPC_FIRST_FPARG_REG ppc_f1
index 04de0ac5876ea17087fb04e4cdf546437044444a..195894f8cbf1eecfa6997df325edc00fd9caf643 100644 (file)
@@ -983,7 +983,8 @@ check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain)
        for (klass = obj->vtable->klass; klass; klass = klass->parent) {
                int i;
 
-               for (i = 0; i < klass->field.count; ++i) {
+               int fcount = mono_class_get_field_count (klass);
+               for (i = 0; i < fcount; ++i) {
                        if (klass->fields[i].offset == offset) {
                                field = &klass->fields[i];
                                break;
index 92276ab63b24fd4b96fd54bca9a14515e31ee814..b3114b1524d80d38ac70410b20b4135ae8f81daf 100644 (file)
@@ -473,7 +473,8 @@ BASE_TEST_CS_SRC_UNIVERSAL=         \
        abort-cctor.cs  \
        thread-native-exit.cs \
        reference-loader.cs \
-       thread-suspend-suspended.cs
+       thread-suspend-suspended.cs \
+       thread-suspend-selfsuspended.cs
 
 if INSTALL_MOBILE_STATIC
 BASE_TEST_CS_SRC= \
diff --git a/mono/tests/thread-suspend-selfsuspended.cs b/mono/tests/thread-suspend-selfsuspended.cs
new file mode 100644 (file)
index 0000000..c9681df
--- /dev/null
@@ -0,0 +1,42 @@
+
+using System;
+using System.Threading;
+
+class Driver
+{
+       public static void Main ()
+       {
+               bool finished = false;
+
+               Thread t1 = Thread.CurrentThread;
+
+               Thread t2 = new Thread (() => {
+                       while (!finished) {
+                               GC.Collect ();
+
+                               try {
+                                       t1.Resume ();
+                               } catch (ThreadStateException) {
+                               }
+
+                               Thread.Yield ();
+                       }
+               });
+
+               t2.Start ();
+
+               Thread.Sleep (10);
+
+               for (int i = 0; i < 50 * 40 * 20; ++i) {
+                       Thread.CurrentThread.Suspend ();
+                       if ((i + 1) % (50) == 0)
+                               Console.Write (".");
+                       if ((i + 1) % (50 * 40) == 0)
+                               Console.WriteLine ();
+               }
+
+               finished = true;
+
+               t2.Join ();
+       }
+}
index e8d52d23a289dfc2e2eb355c47df0c318e89ea1f..499c37846b714eea7f0e525f1b1dd04aed3e09e7 100644 (file)
@@ -573,40 +573,40 @@ typedef struct {
 
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
-               "std 0, 0(%0)\n"        \
-               "std 1, 4(%0)\n"        \
-               "std 0, 4*0+8(%0)\n"    \
-               "std 1, 4*1+8(%0)\n"    \
-               "std 2, 4*2+8(%0)\n"    \
-               "std 3, 4*3+8(%0)\n"    \
-               "std 4, 4*4+8(%0)\n"    \
-               "std 5, 4*5+8(%0)\n"    \
-               "std 6, 4*6+8(%0)\n"    \
-               "std 7, 4*7+8(%0)\n"    \
-               "std 8, 4*8+8(%0)\n"    \
-               "std 9, 4*9+8(%0)\n"    \
-               "std 10, 4*10+8(%0)\n"  \
-               "std 11, 4*11+8(%0)\n"  \
-               "std 12, 4*12+8(%0)\n"  \
-               "std 13, 4*13+8(%0)\n"  \
-               "std 14, 4*14+8(%0)\n"  \
-               "std 15, 4*15+8(%0)\n"  \
-               "std 16, 4*16+8(%0)\n"  \
-               "std 17, 4*17+8(%0)\n"  \
-               "std 18, 4*18+8(%0)\n"  \
-               "std 19, 4*19+8(%0)\n"  \
-               "std 20, 4*20+8(%0)\n"  \
-               "std 21, 4*21+8(%0)\n"  \
-               "std 22, 4*22+8(%0)\n"  \
-               "std 23, 4*23+8(%0)\n"  \
-               "std 24, 4*24+8(%0)\n"  \
-               "std 25, 4*25+8(%0)\n"  \
-               "std 26, 4*26+8(%0)\n"  \
-               "std 27, 4*27+8(%0)\n"  \
-               "std 28, 4*28+8(%0)\n"  \
-               "std 29, 4*29+8(%0)\n"  \
-               "std 30, 4*30+8(%0)\n"  \
-               "std 31, 4*31+8(%0)\n"  \
+               "stw 0, 0(%0)\n"        \
+               "stw 1, 4(%0)\n"        \
+               "stw 0, 4*0+8(%0)\n"    \
+               "stw 1, 4*1+8(%0)\n"    \
+               "stw 2, 4*2+8(%0)\n"    \
+               "stw 3, 4*3+8(%0)\n"    \
+               "stw 4, 4*4+8(%0)\n"    \
+               "stw 5, 4*5+8(%0)\n"    \
+               "stw 6, 4*6+8(%0)\n"    \
+               "stw 7, 4*7+8(%0)\n"    \
+               "stw 8, 4*8+8(%0)\n"    \
+               "stw 9, 4*9+8(%0)\n"    \
+               "stw 10, 4*10+8(%0)\n"  \
+               "stw 11, 4*11+8(%0)\n"  \
+               "stw 12, 4*12+8(%0)\n"  \
+               "stw 13, 4*13+8(%0)\n"  \
+               "stw 14, 4*14+8(%0)\n"  \
+               "stw 15, 4*15+8(%0)\n"  \
+               "stw 16, 4*16+8(%0)\n"  \
+               "stw 17, 4*17+8(%0)\n"  \
+               "stw 18, 4*18+8(%0)\n"  \
+               "stw 19, 4*19+8(%0)\n"  \
+               "stw 20, 4*20+8(%0)\n"  \
+               "stw 21, 4*21+8(%0)\n"  \
+               "stw 22, 4*22+8(%0)\n"  \
+               "stw 23, 4*23+8(%0)\n"  \
+               "stw 24, 4*24+8(%0)\n"  \
+               "stw 25, 4*25+8(%0)\n"  \
+               "stw 26, 4*26+8(%0)\n"  \
+               "stw 27, 4*27+8(%0)\n"  \
+               "stw 28, 4*28+8(%0)\n"  \
+               "stw 29, 4*29+8(%0)\n"  \
+               "stw 30, 4*30+8(%0)\n"  \
+               "stw 31, 4*31+8(%0)\n"  \
                "stfd 0, 8*0+4*32+8(%0)\n"      \
                "stfd 1, 8*1+4*32+8(%0)\n"      \
                "stfd 2, 8*2+4*32+8(%0)\n"      \
@@ -640,7 +640,7 @@ typedef struct {
                "stfd 30, 8*30+4*32+8(%0)\n"    \
                "stfd 31, 8*31+4*32+8(%0)\n"    \
                : : "r" (&(ctx))        \
-               : "memory"                      \
+               : "memory", "r0"        \
        )
 
 #endif
index 7696363229752a26592359024679133255b87cc9..27acdda1f7117680e9c6bb27467e8f8b7b4d3c59 100644 (file)
@@ -156,50 +156,6 @@ STATE_BLOCKING_AND_SUSPENDED: This is a bug in coop x suspend that resulted the
        }
 }
 
-/*
-This transition initiates the suspension of the current thread.
-*/
-void
-mono_threads_transition_request_self_suspension (MonoThreadInfo *info)
-{
-       int raw_state, cur_state, suspend_count;
-       g_assert (info ==  mono_thread_info_current ());
-
-retry_state_change:
-       UNWRAP_THREAD_STATE (raw_state, cur_state, suspend_count, info);
-
-       switch (cur_state) {
-       case STATE_RUNNING: //Post a self suspend request
-               if (!(suspend_count == 0))
-                       mono_fatal_with_history ("suspend_count = %d, but should be == 0", suspend_count);
-               if (InterlockedCompareExchange (&info->thread_state, build_thread_state (STATE_SELF_SUSPEND_REQUESTED, 1), raw_state) != raw_state)
-                       goto retry_state_change;
-               trace_state_change ("SELF_SUSPEND_REQUEST", info, raw_state, STATE_SELF_SUSPEND_REQUESTED, 1);
-               break;
-
-       case STATE_ASYNC_SUSPEND_REQUESTED: //Bump the suspend count but don't change the request type as async takes preference
-               if (!(suspend_count > 0 && suspend_count < THREAD_SUSPEND_COUNT_MAX))
-                       mono_fatal_with_history ("suspend_count = %d, but should be > 0 and < THREAD_SUSPEND_COUNT_MAX", suspend_count);
-               if (InterlockedCompareExchange (&info->thread_state, build_thread_state (cur_state, suspend_count + 1), raw_state) != raw_state)
-                       goto retry_state_change;
-               trace_state_change ("SUSPEND_REQUEST", info, raw_state, cur_state, 1);
-               break;
-/*
-Other states:
-STATE_ASYNC_SUSPENDED: Code should not be running while suspended.
-STATE_SELF_SUSPENDED: Code should not be running while suspended.
-STATE_SELF_SUSPEND_REQUESTED: Self suspends should not nest as begin/end should be paired. [1]
-STATE_BLOCKING:
-STATE_BLOCKING_AND_SUSPENDED: Self suspension cannot be started when the thread is in blocking state as it must finish first
-
-[1] This won't trap this sequence of requests: self suspend, async suspend and self suspend. 
-If this turns to be an issue we can introduce a new suspend request state for when both have been requested.
-*/
-       default:
-               mono_fatal_with_history ("Cannot transition thread %p from %s with SUSPEND_REQUEST", mono_thread_info_get_tid (info), state_name (cur_state));
-       }
-}
-
 /*
 This transition initiates the suspension of another thread.
 
index d97797e8b68829c5da42b402ae751de6a11cd6e1..0b3f71b85d3587bb7650dcb4852100b6737951a4 100644 (file)
@@ -350,7 +350,7 @@ register_thread (MonoThreadInfo *info, gpointer baseptr)
 
        info->handle = g_new0 (MonoThreadHandle, 1);
        info->handle->ref = 1;
-       mono_os_event_init (&info->handle->event, TRUE, FALSE);
+       mono_os_event_init (&info->handle->event, FALSE);
 
        mono_os_sem_init (&info->resume_semaphore, 0);
 
@@ -721,53 +721,6 @@ mono_threads_get_runtime_callbacks (void)
        return &runtime_callbacks;
 }
 
-/*
-Signal that the current thread wants to be suspended.
-This function can be called without holding the suspend lock held.
-To finish suspending, call mono_suspend_check.
-*/
-void
-mono_thread_info_begin_self_suspend (void)
-{
-       g_assert (!mono_threads_is_coop_enabled ());
-
-       MonoThreadInfo *info = mono_thread_info_current_unchecked ();
-       if (!info)
-               return;
-
-       THREADS_SUSPEND_DEBUG ("BEGIN SELF SUSPEND OF %p\n", info);
-       mono_threads_transition_request_self_suspension (info);
-}
-
-void
-mono_thread_info_end_self_suspend (void)
-{
-       MonoThreadInfo *info;
-
-       g_assert (!mono_threads_is_coop_enabled ());
-
-       info = mono_thread_info_current ();
-       if (!info)
-               return;
-       THREADS_SUSPEND_DEBUG ("FINISH SELF SUSPEND OF %p\n", info);
-
-       mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
-
-       /* commit the saved state and notify others if needed */
-       switch (mono_threads_transition_state_poll (info)) {
-       case SelfSuspendResumed:
-               return;
-       case SelfSuspendWait:
-               mono_thread_info_wait_for_resume (info);
-               break;
-       case SelfSuspendNotifyAndWait:
-               mono_threads_notify_initiator_of_suspend (info);
-               mono_thread_info_wait_for_resume (info);
-               mono_threads_notify_initiator_of_resume (info);
-               break;
-       }
-}
-
 static gboolean
 mono_thread_info_core_resume (MonoThreadInfo *info)
 {
index a9776c32dbf8dc99a4e47fef09064210cdf23848..b076433999ba43c501b23a0d934abe798cd0f64a 100644 (file)
@@ -29,6 +29,7 @@ typedef DWORD MonoNativeThreadId;
 typedef HANDLE MonoNativeThreadHandle; /* unused */
 
 typedef DWORD mono_native_thread_return_t;
+typedef DWORD mono_thread_start_return_t;
 
 #define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (tid)
 #define MONO_UINT_TO_NATIVE_THREAD_ID(tid) ((MonoNativeThreadId)(tid))
@@ -55,6 +56,7 @@ typedef pid_t MonoNativeThreadHandle;
 typedef pthread_t MonoNativeThreadId;
 
 typedef void* mono_native_thread_return_t;
+typedef gsize mono_thread_start_return_t;
 
 #define MONO_NATIVE_THREAD_ID_TO_UINT(tid) (gsize)(tid)
 #define MONO_UINT_TO_NATIVE_THREAD_ID(tid) (MonoNativeThreadId)(gsize)(tid)
@@ -330,15 +332,6 @@ mono_thread_info_resume (MonoNativeThreadId tid);
 void
 mono_thread_info_safe_suspend_and_run (MonoNativeThreadId id, gboolean interrupt_kernel, MonoSuspendThreadCallback callback, gpointer user_data);
 
-//XXX new API, fix the world
-void
-mono_thread_info_begin_self_suspend (void);
-
-void
-mono_thread_info_end_self_suspend (void);
-
-//END of new API
-
 void
 mono_thread_info_setup_async_call (THREAD_INFO_TYPE *info, void (*target_func)(void*), void *user_data);
 
@@ -565,7 +558,6 @@ typedef enum {
 
 void mono_threads_transition_attach (THREAD_INFO_TYPE* info);
 gboolean mono_threads_transition_detach (THREAD_INFO_TYPE *info);
-void mono_threads_transition_request_self_suspension (THREAD_INFO_TYPE *info);
 MonoRequestAsyncSuspendResult mono_threads_transition_request_async_suspension (THREAD_INFO_TYPE *info);
 MonoSelfSupendResult mono_threads_transition_state_poll (THREAD_INFO_TYPE *info);
 MonoResumeResult mono_threads_transition_request_resume (THREAD_INFO_TYPE* info);
index a2678b4f949180c4530bc4a6bab5e009e4b8aad1..06e9639d0c2f010959f5d306f7aa46c3f24c78c4 100644 (file)
@@ -27,7 +27,7 @@ initialize (void)
 }
 
 void
-mono_os_event_init (MonoOSEvent *event, gboolean manual, gboolean initial)
+mono_os_event_init (MonoOSEvent *event, gboolean initial)
 {
        g_assert (event);
 
@@ -36,8 +36,6 @@ mono_os_event_init (MonoOSEvent *event, gboolean manual, gboolean initial)
        mono_os_mutex_init (&event->mutex);
        mono_os_cond_init (&event->cond);
        event->signalled = initial;
-       event->manual = manual;
-       event->set_count = (initial && !manual) ? 1 : 0;
 }
 
 void
@@ -51,23 +49,10 @@ mono_os_event_destroy (MonoOSEvent *event)
        mono_os_cond_destroy (&event->cond);
 }
 
-static void
-mono_os_event_signal (MonoOSEvent *event, gboolean broadcast)
+static gboolean
+mono_os_event_is_signalled (MonoOSEvent *event)
 {
-       g_assert (event);
-
-       mono_os_mutex_lock (&signal_mutex);
-
-       event->signalled = TRUE;
-
-       if (broadcast)
-               mono_os_cond_broadcast (&event->cond);
-       else
-               mono_os_cond_signal (&event->cond);
-
-       mono_os_cond_broadcast (&signal_cond);
-
-       mono_os_mutex_unlock (&signal_mutex);
+       return event->signalled;
 }
 
 void
@@ -78,15 +63,15 @@ mono_os_event_set (MonoOSEvent *event)
        g_assert (event);
 
        mono_os_mutex_lock (&event->mutex);
+       mono_os_mutex_lock (&signal_mutex);
 
-       if (event->manual) {
-               mono_os_event_signal (event, TRUE);
-       } else {
-               event->set_count = 1;
-               mono_os_event_signal (event, FALSE);
-       }
+       event->signalled = TRUE;
+
+       mono_os_cond_broadcast (&event->cond);
+       mono_os_cond_broadcast (&signal_cond);
 
        mono_os_mutex_unlock (&event->mutex);
+       mono_os_mutex_unlock (&signal_mutex);
 }
 
 void
@@ -98,78 +83,34 @@ mono_os_event_reset (MonoOSEvent *event)
 
        mono_os_mutex_lock (&event->mutex);
 
-       if (event->signalled)
-               event->signalled = FALSE;
-
-       event->set_count = 0;
+       event->signalled = FALSE;
 
        mono_os_mutex_unlock (&event->mutex);
 }
 
-static gboolean
-mono_os_event_own (MonoOSEvent *event)
-{
-       g_assert (event);
-
-       if (!event->signalled)
-               return FALSE;
-
-       if (!event->manual) {
-               g_assert (event->set_count > 0);
-               event->set_count -= 1;
-
-               if (event->set_count == 0)
-                       mono_os_event_signal (event, FALSE);
-       }
-
-       return TRUE;
-}
-
 MonoOSEventWaitRet
 mono_os_event_wait_one (MonoOSEvent *event, guint32 timeout)
 {
-       MonoOSEventWaitRet ret;
-       gint64 start;
-
-       g_assert (mono_lazy_is_initialized (&status));
-
-       g_assert (event);
-
-       mono_os_mutex_lock (&event->mutex);
+       return mono_os_event_wait_multiple (&event, 1, TRUE, timeout);
+}
 
-       if (timeout != MONO_INFINITE_WAIT)
-               start = mono_msec_ticks ();
+typedef struct {
+       guint32 ref;
+       MonoOSEvent event;
+} OSEventWaitData;
 
-       for (;;) {
-               if (mono_os_event_own (event)) {
-                       ret = MONO_OS_EVENT_WAIT_RET_SUCCESS_0;
-                       goto done;
-               }
-
-               if (timeout == MONO_INFINITE_WAIT) {
-                       mono_os_cond_wait (&event->cond, &event->mutex);
-               } else {
-                       gint64 elapsed;
-                       gint res;
+static void
+signal_and_unref (gpointer user_data)
+{
+       OSEventWaitData *data;
 
-                       elapsed = mono_msec_ticks () - start;
-                       if (elapsed >= timeout) {
-                               ret = MONO_OS_EVENT_WAIT_RET_TIMEOUT;
-                               goto done;
-                       }
+       data = (OSEventWaitData*) user_data;
 
-                       res = mono_os_cond_timedwait (&event->cond, &event->mutex, timeout - elapsed);
-                       if (res != 0) {
-                               ret = MONO_OS_EVENT_WAIT_RET_TIMEOUT;
-                               goto done;
-                       }
-               }
+       mono_os_event_set (&data->event);
+       if (InterlockedDecrement ((gint32*) &data->ref) == 0) {
+               mono_os_event_destroy (&data->event);
+               g_free (data);
        }
-
-done:
-       mono_os_mutex_unlock (&event->mutex);
-
-       return ret;
 }
 
 static void
@@ -206,6 +147,9 @@ MonoOSEventWaitRet
 mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waitall, guint32 timeout)
 {
        MonoOSEventWaitRet ret;
+       MonoOSEvent *innerevents [MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS + 1];
+       OSEventWaitData *data;
+       gboolean alerted;
        gint64 start;
        gint i;
 
@@ -215,11 +159,23 @@ mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waita
        g_assert (nevents > 0);
        g_assert (nevents <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS);
 
-       if (nevents == 1)
-               return mono_os_event_wait_one (events [0], timeout);
-
-       for (i = 0; i < nevents; ++i) {
+       for (i = 0; i < nevents; ++i)
                g_assert (events [i]);
+
+       memcpy (innerevents, events, sizeof (MonoOSEvent*) * nevents);
+
+       data = g_new0 (OSEventWaitData, 1);
+       data->ref = 2;
+       mono_os_event_init (&data->event, FALSE);
+
+       innerevents [nevents ++] = &data->event;
+
+       alerted = FALSE;
+       mono_thread_info_install_interrupt (signal_and_unref, data, &alerted);
+       if (alerted) {
+               mono_os_event_destroy (&data->event);
+               g_free (data);
+               return MONO_OS_EVENT_WAIT_RET_ALERTED;
        }
 
        if (timeout != MONO_INFINITE_WAIT)
@@ -229,27 +185,27 @@ mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waita
                gint count, lowest;
                gboolean signalled;
 
-               mono_os_event_lock_events (events, nevents);
+               mono_os_event_lock_events (innerevents, nevents);
 
                count = 0;
                lowest = -1;
 
-               for (i = 0; i < nevents; ++i) {
-                       if (events [i]->signalled) {
+               for (i = 0; i < nevents - 1; ++i) {
+                       if (mono_os_event_is_signalled (innerevents [i])) {
                                count += 1;
                                if (lowest == -1)
                                        lowest = i;
                        }
                }
 
-               signalled = (waitall && count == nevents) || (!waitall && count > 0);
-
-               if (signalled) {
-                       for (i = 0; i < nevents; ++i)
-                               mono_os_event_own (events [i]);
-               }
+               if (mono_os_event_is_signalled (&data->event))
+                       signalled = TRUE;
+               else if (waitall)
+                       signalled = (count == nevents - 1);
+               else /* waitany */
+                       signalled = (count > 0);
 
-               mono_os_event_unlock_events (events, nevents);
+               mono_os_event_unlock_events (innerevents, nevents);
 
                if (signalled) {
                        ret = MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + lowest;
@@ -258,18 +214,20 @@ mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waita
 
                mono_os_mutex_lock (&signal_mutex);
 
-               if (waitall) {
+               if (mono_os_event_is_signalled (&data->event)) {
                        signalled = TRUE;
-                       for (i = 0; i < nevents; ++i) {
-                               if (!events [i]->signalled) {
+               } else if (waitall) {
+                       signalled = TRUE;
+                       for (i = 0; i < nevents - 1; ++i) {
+                               if (!mono_os_event_is_signalled (innerevents [i])) {
                                        signalled = FALSE;
                                        break;
                                }
                        }
                } else {
                        signalled = FALSE;
-                       for (i = 0; i < nevents; ++i) {
-                               if (events [i]->signalled) {
+                       for (i = 0; i < nevents - 1; ++i) {
+                               if (mono_os_event_is_signalled (innerevents [i])) {
                                        signalled = TRUE;
                                        break;
                                }
@@ -308,5 +266,17 @@ mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waita
        }
 
 done:
+       mono_thread_info_uninstall_interrupt (&alerted);
+       if (alerted) {
+               if (InterlockedDecrement ((gint32*) &data->ref) == 0) {
+                       mono_os_event_destroy (&data->event);
+                       g_free (data);
+               }
+               return MONO_OS_EVENT_WAIT_RET_ALERTED;
+       }
+
+       mono_os_event_destroy (&data->event);
+       g_free (data);
+
        return ret;
 }
index 422283acf078a0613d7644c4b88e19f744288b45..e28833c0d8f1141623cfe8ccbc41a65787fa83c7 100644 (file)
 #include "atomic.h"
 
 void
-mono_os_event_init (MonoOSEvent *event, gboolean manual, gboolean initial)
+mono_os_event_init (MonoOSEvent *event, gboolean initial)
 {
        g_assert (event);
 
-       event->handle = CreateEvent (NULL, manual, initial, NULL);
+       event->handle = CreateEvent (NULL, TRUE, initial, NULL);
        if (G_UNLIKELY (!event->handle))
                g_error ("%s: CreateEvent failed with error %d", __func__, GetLastError ());
 }
index 81260b983614f0a79063c357ffe34ad618d87044..3f04f0bfcafbbc4554d24431c095928825d80567 100644 (file)
@@ -29,14 +29,12 @@ struct _MonoOSEvent {
 #else
        mono_mutex_t mutex;
        mono_cond_t cond;
-       gboolean manual;
        gboolean signalled;
-       guint32 set_count;
 #endif
 };
 
 void
-mono_os_event_init (MonoOSEvent *event, gboolean manual, gboolean initial);
+mono_os_event_init (MonoOSEvent *event, gboolean initial);
 
 void
 mono_os_event_destroy (MonoOSEvent *event);
index 15984b6c059dfdabc3d03ba6f7f91df67ab3bc06..1ac7e077af462557f02a22fb47bf04a457638998 100644 (file)
@@ -13,13 +13,13 @@ ifdef RAX
 PUBLIC mono_context_get_current
 
 mono_context_get_current PROC
-;rdi has the ctx ptr
+;rcx has the ctx ptr
        mov [rcx + 00h], rax
-       mov [rcx + 08h], rbx
-       mov [rcx + 10h], rcx
-       mov [rcx + 18h], rdx
-       mov [rcx + 20h], rbp
-       mov [rcx + 28h], rsp
+       mov [rcx + 08h], rcx
+       mov [rcx + 10h], rdx
+       mov [rcx + 18h], rbx
+       mov [rcx + 20h], rsp
+       mov [rcx + 28h], rbp
        mov [rcx + 30h], rsi
        mov [rcx + 38h], rdi
        mov [rcx + 40h], r8
diff --git a/packaging/MacSDK/__init__.py b/packaging/MacSDK/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packaging/MacSDK/fsharp.py b/packaging/MacSDK/fsharp.py
new file mode 100644 (file)
index 0000000..9e53489
--- /dev/null
@@ -0,0 +1,24 @@
+class FsharpPackage(GitHubTarballPackage):
+
+    def __init__(self):
+        GitHubTarballPackage.__init__(self,
+                                      'fsharp', 'fsharp',
+                                      '4.0.1.9',
+                                      '0a6c66a8f18eb8a5c4d0bfac61d883b6994a918a',
+                                      configure='./configure --prefix="%{package_prefix}"')
+
+        self.extra_stage_files = [
+            'lib/mono/xbuild/Microsoft/VisualStudio/v/FSharp/Microsoft.FSharp.Targets']
+
+    def prep(self):
+        Package.prep(self)
+
+        for p in range(1, len(self.sources)):
+            self.sh('patch -p1 < "%{local_sources[' + str(p) + ']}"')
+
+    def build(self):
+        self.sh('autoreconf')
+        Package.configure(self)
+        Package.make(self)
+
+FsharpPackage()
diff --git a/packaging/MacSDK/gdk-pixbuf/0001-pixbuf-Add-getter-setter-for-the-2x-variants.patch b/packaging/MacSDK/gdk-pixbuf/0001-pixbuf-Add-getter-setter-for-the-2x-variants.patch
new file mode 100644 (file)
index 0000000..2ca1c6a
--- /dev/null
@@ -0,0 +1,56 @@
+From f6d2db5a0c105785ee6f03717966ef0dbb1421f6 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Tue, 16 Jul 2013 10:32:11 +0200
+Subject: [PATCH] pixbuf: Add getter/setter for the 2x variants
+
+---
+ gdk-pixbuf/gdk-pixbuf-core.h |  3 +++
+ gdk-pixbuf/gdk-pixbuf.c      | 22 ++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/gdk-pixbuf/gdk-pixbuf-core.h b/gdk-pixbuf/gdk-pixbuf-core.h
+index eb4d0a1..60c4ea3 100644
+--- a/gdk-pixbuf/gdk-pixbuf-core.h
++++ b/gdk-pixbuf/gdk-pixbuf-core.h
+@@ -474,6 +474,9 @@ GdkPixbuf *gdk_pixbuf_apply_embedded_orientation (GdkPixbuf *src);
+ const gchar * gdk_pixbuf_get_option (GdkPixbuf   *pixbuf,
+                                               const gchar *key);
+
++GdkPixbuf * gdk_pixbuf_get_hires_variant (GdkPixbuf *pixbuf);
++void        gdk_pixbuf_set_hires_variant (GdkPixbuf *pixbuf,
++                                          GdkPixbuf *hires);
+
+ G_END_DECLS
+
+diff --git a/gdk-pixbuf/gdk-pixbuf.c b/gdk-pixbuf/gdk-pixbuf.c
+index 0e13f27..d61f2c7 100644
+--- a/gdk-pixbuf/gdk-pixbuf.c
++++ b/gdk-pixbuf/gdk-pixbuf.c
+@@ -990,3 +990,25 @@ gdk_pixbuf_get_property (GObject         *object,
+                   break;
+           }
+ }
++
++GdkPixbuf *
++gdk_pixbuf_get_hires_variant (GdkPixbuf *pixbuf)
++{
++        g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
++
++        return g_object_get_data (G_OBJECT (pixbuf),
++                                  "gdk-pixbuf-2x-variant");
++}
++
++void
++gdk_pixbuf_set_hires_variant (GdkPixbuf *pixbuf,
++                              GdkPixbuf *hires)
++{
++        g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
++        g_return_if_fail (GDK_IS_PIXBUF (hires));
++
++        g_object_set_data_full (G_OBJECT (pixbuf),
++                                "gdk-pixbuf-2x-variant",
++                                g_object_ref (hires),
++                                (GDestroyNotify) g_object_unref);
++}
+--
+1.8.3.2
diff --git a/packaging/MacSDK/gdk-pixbuf/0001-pixbuf-load-2x-variants-as-pixbuf-gobject-data.patch b/packaging/MacSDK/gdk-pixbuf/0001-pixbuf-load-2x-variants-as-pixbuf-gobject-data.patch
new file mode 100644 (file)
index 0000000..80d3d39
--- /dev/null
@@ -0,0 +1,99 @@
+>From de5d91aa15cc98795a68c8e553eb4baadaa0e501 Mon Sep 17 00:00:00 2001
+From: Carlos Garnacho <carlosg@gnome.org>
+Date: Fri, 17 May 2013 15:56:28 +0200
+Subject: [PATCH] pixbuf: load "@2x" variants as pixbuf gobject data
+
+if a variant of the filename is found that has a "@2x" appended
+to the file name (before the extension), such file is loaded
+and added as GObject data to the pixbuf
+---
+ gdk-pixbuf/gdk-pixbuf-io.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+
+diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c
+index dac21b8..ed98cd3 100644
+--- a/gdk-pixbuf/gdk-pixbuf-io.c
++++ b/gdk-pixbuf/gdk-pixbuf-io.c
+@@ -1025,6 +1025,40 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
+         return pixbuf;
+ }
+
++static gboolean
++_gdk_pixbuf_file_is_scaled (const gchar *filename)
++{
++      gchar *basename, *ext;
++
++      basename = g_path_get_basename (filename);
++      ext = strrchr (basename, '.');
++
++      if (!ext)
++              ext = &basename[strlen(basename)];
++
++      if (ext > basename + 3 && strncmp (ext - 3, "@2x", 3) == 0)
++              return TRUE;
++
++      return FALSE;
++}
++
++static gchar *
++_gdk_pixbuf_compose_scaled_filename (const gchar *filename)
++{
++      gchar *ext, *first, *composed;
++
++      ext = strrchr (filename, '.');
++
++      if (!ext)
++              return NULL;
++
++      first = g_strndup (filename, ext - filename);
++      composed = g_strdup_printf ("%s@2x%s", first, ext);
++      g_free (first);
++
++      return composed;
++}
++
+ /**
+  * gdk_pixbuf_new_from_file:
+  * @filename: Name of file to load, in the GLib file name encoding
+@@ -1049,11 +1083,13 @@ gdk_pixbuf_new_from_file (const char *filename,
+         guchar buffer[SNIFF_BUFFER_SIZE];
+         GdkPixbufModule *image_module;
+         gchar *display_name;
++      gboolean filename_is_scaled;
+
+         g_return_val_if_fail (filename != NULL, NULL);
+         g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+         display_name = g_filename_display_name (filename);
++      filename_is_scaled = _gdk_pixbuf_file_is_scaled (filename);
+
+         f = g_fopen (filename, "rb");
+         if (!f) {
+@@ -1097,6 +1133,25 @@ gdk_pixbuf_new_from_file (const char *filename,
+         pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error);
+         fclose (f);
+
++      if (pixbuf && !filename_is_scaled) {
++              GdkPixbuf *scaled_pixbuf = NULL;
++              gchar *scaled_filename;
++
++              scaled_filename = _gdk_pixbuf_compose_scaled_filename (filename);
++
++              if (scaled_filename) {
++                      scaled_pixbuf = gdk_pixbuf_new_from_file (scaled_filename, NULL);
++                      g_free (scaled_filename);
++              }
++
++              if (scaled_pixbuf) {
++                      g_object_set_data_full (G_OBJECT (pixbuf),
++                                                "gdk-pixbuf-2x-variant",
++                                                scaled_pixbuf,
++                                                (GDestroyNotify) g_object_unref);
++              }
++      }
++
+         if (pixbuf == NULL && error != NULL && *error == NULL) {
+
+                 /* I don't trust these crufty longjmp()'ing image libs
+--
+1.8.3.rc1
diff --git a/packaging/MacSDK/gtkrc b/packaging/MacSDK/gtkrc
new file mode 100644 (file)
index 0000000..b1168d6
--- /dev/null
@@ -0,0 +1,216 @@
+include "/Library/Frameworks/Mono.framework/Versions/Current/share/themes/Clearlooks/gtk-2.0/gtkrc"
+#gtk-icon-theme-name = "OSX"
+gtk-icon-theme-name = "Tango"
+gtk_color_scheme = "fg_color:#222\nbg_color:#e6e6e6\nbase_color:#f9f9f9\ntext_color:#222\nselected_bg_color:#788ab0\nselected_fg_color:#fff"
+gtk-menu-popup-delay = 1
+gtk-button-images = 0
+gtk-menu-images = 0
+gtk-enable-mnemonics = 0
+
+style "theme-default"
+{
+    GtkButton      ::default_border    = { 0, 0, 0, 0 }
+    GtkRange       ::trough_border     = 0
+    GtkPaned       ::handle_size       = 8
+    GtkRange       ::slider_width      = 15
+    GtkRange       ::stepper_size      = 15
+    GtkScrollbar   ::min_slider_length = 30
+    GtkCheckButton ::indicator_size    = 14
+    GtkMenuBar     ::internal-padding  = 0
+    GtkTreeView    ::expander_size     = 12
+    GtkExpander    ::expander_size     = 14
+
+    xthickness = 2
+    ythickness = 2
+
+    fg[NORMAL]        = @fg_color #"#000000" # black
+    fg[PRELIGHT]      = @fg_color #"#000000" # black
+    fg[SELECTED]      = @selected_fg_color #"#ffffff" # white
+    fg[ACTIVE]        = @fg_color #"#000000" # black
+    fg[INSENSITIVE]   = darker (@bg_color) #"#b5b3ac" # dark beige
+
+    bg[NORMAL]        = @bg_color # "#ede9e3"
+    bg[PRELIGHT]      = shade (1.02, @bg_color) #"#f9f7f3" # very light beige
+    bg[SELECTED]      = @selected_bg_color # "#5598d7" # deepsky
+    bg[INSENSITIVE]   = @bg_color # "#efebe5" # beige
+    bg[ACTIVE]        = shade (0.9, @bg_color) #"#dcd4c9" #"#d7d3ca" # dark beige
+
+    base[NORMAL]      = @base_color # "#ffffff" # white
+    base[PRELIGHT]    = shade (0.95, @bg_color) # "#5f8ec4" # dark beige
+    base[ACTIVE]      = shade (0.9, @selected_bg_color) # "#a69f91" # darker deepsky
+    base[SELECTED]    = @selected_bg_color # "#5598d7" # deepsky
+    base[INSENSITIVE] = @bg_color # "#e8e5de" # beige
+
+    text[NORMAL]      = @text_color # "#000000" # black
+    text[PRELIGHT]    = @text_color # "#000000" # black
+    text[ACTIVE]      = @selected_fg_color # "#ffffff" # white
+    text[SELECTED]    = @selected_fg_color # "#ffffff" # white
+    text[INSENSITIVE] = darker (@bg_color) # "#b5b3ac" # dark beige
+
+    engine "clearlooks"  {
+      style               = GUMMY   # gummy look
+      toolbarstyle        = 0       # flat toolbars
+      animation           = TRUE    # animated progressbars
+      menubarstyle        = 2       # rounded menus
+      colorize_scrollbar  = TRUE    # colored slider
+    }
+
+    font              = "Lucida Grande 14"
+}
+
+style "theme-wide" = "theme-default"
+{
+    xthickness = 3
+    ythickness = 3
+}
+
+style "theme-text" = "theme-default"
+{
+    #base[SELECTED]     = "#fc9747"  # Outline?
+}
+
+style "theme-toolbar" = "theme-default"
+{
+    #top and bottom border
+    bg[NORMAL] = @bg_color
+}
+
+style "theme-scrollbar" = "theme-default"
+{
+    bg[SELECTED] = shade (1.1, @selected_bg_color)
+}
+
+style "theme-tasklist" = "theme-default"
+{
+    xthickness = 5
+    ythickness = 3
+}
+
+style "theme-menu" = "theme-default"
+{
+    xthickness = 3
+    ythickness = 3
+    bg[NORMAL] = shade (1.1,@bg_color)
+}
+
+style "theme-menu-item" = "theme-default"
+{
+    xthickness = 2
+    ythickness = 4
+    fg[PRELIGHT] = @selected_fg_color
+    text[PRELIGHT] = @selected_fg_color
+    base[PRELIGHT] = @selected_bg_color # Selection color
+}
+
+style "theme-menu-itembar" = "theme-default"
+{
+    xthickness = 0
+    ythickness = 0
+}
+
+style "theme-tree" = "theme-default"
+{
+    xthickness = 2
+    ythickness = 2
+    GtkTreeView::odd-row-color = shade(0.9, @base_color)
+    GtkTreeView::even-row-color = @base_color
+}
+
+style "theme-frame-title" = "theme-default"
+{
+    #fg[NORMAL] = "#f00" #button frames
+}
+
+style "theme-tooltips" = "theme-default"
+{
+    xthickness = 4
+    ythickness = 4
+    bg[NORMAL] = { 1.0,1.0,0.75 }
+}
+
+style "theme-progressbar" = "theme-default"
+{
+    xthickness = 1
+    ythickness = 1
+    fg[PRELIGHT]  = @base_color
+}
+
+style "theme-combo" = "theme-default"
+{
+    xthickness = 2
+    ythickness = 4
+}
+
+style "theme-button" = "theme-wide"
+{
+    bg[NORMAL] = @bg_color
+    bg[PRELIGHT] = shade (1.1, @bg_color)
+    bg[ACTIVE] = shade (0.9, @bg_color)
+    #xthickness = 4
+    #ythickness = 2
+}
+
+style "theme-check" = "theme-button"
+{
+}
+
+style "theme-panel" = "theme-default"
+{
+    xthickness = 3
+    ythickness = 3
+    bg[ACTIVE] = shade (1.1, @selected_bg_color)
+    fg[ACTIVE] = @selected_fg_color
+}
+
+style "theme-notebook" = "theme-wide"
+{
+    base[SELECTED]    = @selected_bg_color  # Tab selection color
+    bg[ACTIVE]        = shade(0.9, @bg_color)  # Unselected tabs
+
+#    engine "clearlooks" {
+#        style = CLASSIC
+#    }
+}
+
+# widget styles
+class "GtkWidget" style "theme-default"
+class "GtkButton" style "theme-button"
+class "GtkCombo"  style "theme-button"
+class "GtkRange"  style "theme-wide"
+class "GtkFrame"  style "theme-wide"
+class "GtkMenu"   style "theme-menu"
+class "GtkEntry"  style "theme-button"
+class "GtkMenuItem"    style "theme-menu-item"
+class "GtkStatusbar"   style "theme-wide"
+class "GtkNotebook"    style "theme-notebook"
+class "GtkProgressBar" style "theme-progressbar"
+class "GtkCheckButton" style "theme-check"
+class "GtkRadioButton" style "theme-check"
+class "GtkToolbar" style "theme-toolbar"
+
+widget_class "*MenuItem.*" style "theme-menu-item"
+
+# combobox stuff
+widget_class "*.GtkComboBox.GtkButton" style "theme-combo"
+widget_class "*.GtkCombo.GtkButton"    style "theme-combo"
+
+# tooltips stuff
+widget_class "*.tooltips.*.GtkToggleButton" style "theme-tasklist"
+widget "gtk-tooltips" style "theme-tooltips"
+
+# treeview stuff
+widget "*GtkTreeView*" style "theme-tree"
+widget_class "*.GtkTreeView.GtkButton" style "theme-tree"
+widget_class "*.GtkCTree.GtkButton" style "theme-tree"
+widget_class "*.GtkList.GtkButton" style "theme-tree"
+widget_class "*.GtkCList.GtkButton" style "theme-tree"
+widget_class "*.GtkFrame.GtkLabel" style "theme-frame-title"
+
+# notebook stuff
+widget_class "*.GtkNotebook.*.GtkEventBox" style "theme-notebook"
+widget_class "*.GtkNotebook.*.GtkViewport" style "theme-notebook"
+
+# scrollbar stuff
+class "GtkScrollbar" style "theme-scrollbar"
+
+gtk-font-name = "Lucida Grande 12"
diff --git a/packaging/MacSDK/ironlangs.py b/packaging/MacSDK/ironlangs.py
new file mode 100644 (file)
index 0000000..0d4e336
--- /dev/null
@@ -0,0 +1,66 @@
+import os
+import string
+
+
+class IronLanguagesPackage(GitHubTarballPackage):
+
+    def __init__(self):
+        GitHubTarballPackage.__init__(self,
+                                      'IronLanguages', 'iron-languages',
+                                      '2.11',
+                                      'de63773744ccf9873c1826470730ae0446fd64d7',
+                                      configure='')
+
+        # override: avoid naming the package 'main' because of the repo name
+        self.sources = [
+            'https://github.com/%{organization}/main/tarball/%{revision}']
+        self.source_dir_name = '%s-%s-%s' % (
+            self.organization, 'main', self.revision[:7])
+
+    def build(self):
+        self.ironruby = os.path.join(
+            self.workspace, 'ironruby', 'bin') + os.sep
+        self.ironpython = os.path.join(
+            self.workspace, 'ironpython', 'bin') + os.sep
+        self.sh(
+            'xbuild /p:Configuration=Release /p:OutDir="%{ironruby}" Solutions/Ruby.sln')
+        self.sh(
+            'xbuild /p:Configuration=Release /p:OutDir="%{ironpython}" Solutions/IronPython.Mono.sln')
+
+    def install_ruby_scripts(self, path, installdir):
+        for cmd, ext in map(os.path.splitext, os.listdir(path)):
+            if ext != '.exe':
+                continue
+            wrapper = os.path.join(self.staged_prefix, "bin", cmd)
+            with open(wrapper, "w") as output:
+                output.write("#!/bin/sh\n")
+                output.write(
+                    "exec {0}/bin/mono {0}/lib/{1}/{2}.exe \"$@\"\n".format(
+                        self.staged_prefix, installdir, cmd))
+            os.chmod(wrapper, 0o755)
+
+    def install_python_scripts(self, path, installdir):
+        for cmd, ext in map(os.path.splitext, os.listdir(path)):
+            if ext != '.exe':
+                continue
+            wrapper = os.path.join(self.staged_prefix, "bin", cmd)
+            with open(wrapper, "w") as output:
+                output.write("#!/bin/sh\n")
+                output.write(
+                    'export IRONPYTHONPATH=/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/\n')
+                output.write(
+                    "exec {0}/bin/mono {0}/lib/{1}/{2}.exe \"$@\"\n".format(
+                        self.staged_prefix, installdir, cmd))
+            os.chmod(wrapper, 0o755)
+
+    def install(self):
+        self.sh("mkdir -p %{staged_prefix}/lib/ironruby/")
+        self.sh("mkdir -p %{staged_prefix}/bin/")
+        self.sh("cp -R %{ironruby} %{staged_prefix}/lib/ironruby/")
+        self.install_ruby_scripts(self.ironruby, 'ironruby')
+
+        self.sh("mkdir -p %{staged_prefix}/lib/ironpython/")
+        self.sh("cp -R %{ironpython} %{staged_prefix}/lib/ironpython/")
+        self.install_python_scripts(self.ironpython, 'ironpython')
+
+IronLanguagesPackage()
diff --git a/packaging/MacSDK/libgdiplus.py b/packaging/MacSDK/libgdiplus.py
new file mode 100644 (file)
index 0000000..e40baac
--- /dev/null
@@ -0,0 +1,8 @@
+GitHubTarballPackage(
+    'mono',
+    'libgdiplus',
+    '2.11',
+    '4e7ab0f555a13a6b2f954c714c4ee5213954ff79',
+    configure='CFLAGS="%{gcc_flags} %{local_gcc_flags} -I/opt/X11/include" ./autogen.sh --prefix="%{package_prefix}"',
+    override_properties={
+        'make': 'C_INCLUDE_PATH="" make'})
diff --git a/packaging/MacSDK/mono-basic.py b/packaging/MacSDK/mono-basic.py
new file mode 100644 (file)
index 0000000..ffdbde0
--- /dev/null
@@ -0,0 +1,12 @@
+
+class MonoBasicPackage (GitHubTarballPackage):
+
+    def __init__(self):
+        GitHubTarballPackage.__init__(self, 'mono', 'mono-basic', '4.6', 'c93133db1d511f994918391f429fee29b9250004',
+                                      configure='./configure --prefix="%{staged_profile}"')
+
+    def install(self):
+        self.sh('./configure --prefix="%{staged_prefix}"')
+        self.sh('make install')
+
+MonoBasicPackage()
diff --git a/packaging/MacSDK/mono-llvm.py b/packaging/MacSDK/mono-llvm.py
new file mode 100644 (file)
index 0000000..cf9e89b
--- /dev/null
@@ -0,0 +1,35 @@
+import os
+
+
+class MonoLlvmPackage (GitHubPackage):
+
+    def __init__(self):
+        GitHubPackage.__init__(self, 'mono', 'llvm', '3.0',
+                               revision='8b1520c8aae53e219cf80cdc0f02ad96600887d6',
+                               configure_flags=[
+                                   '--enable-optimized',
+                                   '--enable-assertions=no',
+                                   '--enable-targets="x86,x86_64"']
+                               )
+
+        # This package would like to be lipoed.
+        self.needs_lipo = True
+
+        # TODO: find out which flags are causing issues. reset ld_flags for the
+        # package
+        self.ld_flags = []
+        self.cpp_flags = []
+
+    def arch_build(self, arch):
+        if arch == 'darwin-64':  # 64-bit  build pass
+            self.local_configure_flags = ['--build=x86_64-apple-darwin11.2.0']
+
+        if arch == 'darwin-32':
+            self.local_configure_flags = ['--build=i386-apple-darwin11.2.0']
+
+        # LLVM says that libstdc++4.6 is broken and we should use libstdc++4.7.
+        # This switches it to the right libstdc++.
+        if Package.profile.name == 'darwin':
+            self.local_configure_flags.extend(['--enable-libcpp=yes'])
+
+MonoLlvmPackage()
diff --git a/packaging/MacSDK/mono.py b/packaging/MacSDK/mono.py
new file mode 100644 (file)
index 0000000..8b9f6b3
--- /dev/null
@@ -0,0 +1,99 @@
+import os
+import re
+
+from bockbuild.package import Package
+from bockbuild.util.util import *
+
+
+class MonoMasterPackage(Package):
+
+    def __init__(self):
+        Package.__init__(self, 'mono', None,
+                         sources=[
+                             Package.profile.git_root],
+                         git_branch=os.getenv('MONO_BRANCH') or None,
+                         revision=os.getenv('MONO_BUILD_REVISION'),
+                         configure_flags=[
+                             '--enable-nls=no',
+                             '--with-ikvm=yes'
+                         ]
+                         )
+        self.source_dir_name = 'mono'
+        # This package would like to be lipoed.
+        self.needs_lipo = True
+
+        # Don't clean the workspace, so we can run 'make check' afterwards
+        self.dont_clean = True
+
+        if Package.profile.name == 'darwin':
+            self.configure_flags.extend([
+                '--with-libgdiplus=%s/lib/libgdiplus.dylib' % Package.profile.staged_prefix,
+                '--enable-loadedllvm',
+                'CXXFLAGS=-stdlib=libc++'
+            ])
+
+            self.sources.extend([
+                # Fixes up pkg-config usage on the Mac
+                'patches/mcs-pkgconfig.patch'
+            ])
+        else:
+            self.configure_flags.extend([
+                '--with-libgdiplus=%s/lib/libgdiplus.so' % Package.profile.staged_prefix
+            ])
+
+        self.gcc_flags.extend(['-O2'])
+
+        self.configure = './autogen.sh --prefix="%{package_prefix}"'
+
+        self.extra_stage_files = ['etc/mono/config']
+
+    def build(self):
+        self.make = '%s EXTERNAL_MCS=%s EXTERNAL_RUNTIME=%s' % (
+            self.make, self.profile.env.system_mcs, self.profile.env.system_mono)
+        Package.build(self)
+
+    def prep(self):
+        Package.prep(self)
+        for p in range(1, len(self.local_sources)):
+            self.sh('patch -p1 < "%{local_sources[' + str(p) + ']}"')
+
+    def arch_build(self, arch):
+        if arch == 'darwin-64':  # 64-bit build pass
+            self.local_gcc_flags = ['-m64']
+            self.local_configure_flags = ['--build=x86_64-apple-darwin11.2.0']
+
+        if arch == 'darwin-32':  # 32-bit build pass
+            self.local_gcc_flags = ['-m32']
+            self.local_configure_flags = ['--build=i386-apple-darwin11.2.0']
+
+        self.local_configure_flags.extend(
+            ['--cache-file=%s/%s-%s.cache' % (self.profile.bockbuild.build_root, self.name, arch)])
+
+    def install(self):
+        Package.install(self)
+
+        registry_dir = os.path.join(
+            self.staged_prefix,
+            "etc",
+            "mono",
+            "registry",
+            "LocalMachine")
+        ensure_dir(registry_dir)
+
+        # Add ImportBefore/ImportAfter files from xbuild to the msbuild
+        # directories
+        xbuild_dir = os.path.join(self.staged_prefix, 'lib/mono/xbuild')
+        new_xbuild_tv_dir = os.path.join(xbuild_dir, self.version)
+        os.makedirs(new_xbuild_tv_dir)
+
+        self.sh('cp -R %s/14.0/Imports %s' % (xbuild_dir, new_xbuild_tv_dir))
+        self.sh(
+            'cp -R %s/14.0/Microsoft.Common.targets %s' %
+            (xbuild_dir, new_xbuild_tv_dir))
+
+    def deploy(self):
+        if bockbuild.cmd_options.arch == 'darwin-universal':
+            os.symlink('mono-sgen64', '%s/bin/mono64' % self.staged_profile)
+            os.symlink('mono-sgen32', '%s/bin/mono32' % self.staged_profile)
+
+MonoMasterPackage()
diff --git a/packaging/MacSDK/msbuild.py b/packaging/MacSDK/msbuild.py
new file mode 100644 (file)
index 0000000..0e16af1
--- /dev/null
@@ -0,0 +1,44 @@
+import fileinput
+
+
+class MSBuild (GitHubPackage):
+
+    def __init__(self):
+        GitHubPackage.__init__(self, 'mono', 'msbuild', '15.0',
+                               git_branch='xplat-c8p')
+
+    def build(self):
+        self.sh('./cibuild.sh --scope Compile --target Mono --host Mono')
+
+    def install(self):
+        # adjusted from 'install-mono-prefix.sh'
+
+        build_output = 'bin/Debug-MONO/OSX_Deployment'
+        new_location = os.path.join(
+            self.staged_prefix,
+            'lib/mono/msbuild/%s/bin' %
+            self.version)
+        bindir = os.path.join(self.staged_prefix, 'bin')
+
+        os.makedirs(new_location)
+        self.sh('cp -R %s/* %s' % (build_output, new_location))
+
+        os.makedirs(bindir)
+
+        self.sh('cp msbuild-mono-deploy.in %s/msbuild' % bindir)
+
+        for line in fileinput.input('%s/msbuild' % bindir, inplace=True):
+            line = line.replace('@bindir@', '%s/bin' % self.staged_prefix)
+            line = line.replace(
+                '@mono_instdir@',
+                '%s/lib/mono' %
+                self.staged_prefix)
+            print line
+
+        for excluded in glob.glob("%s/*UnitTests*" % new_location):
+            self.rm(excluded)
+
+        for excluded in glob.glob("%s/*xunit*" % new_location):
+            self.rm(excluded)
+
+MSBuild()
diff --git a/packaging/MacSDK/nuget.py b/packaging/MacSDK/nuget.py
new file mode 100644 (file)
index 0000000..321bedf
--- /dev/null
@@ -0,0 +1,18 @@
+
+class NuGetPackage(GitHubPackage):
+
+    def __init__(self):
+        GitHubPackage.__init__(self,
+                               'mono', 'nuget',
+                               '2.12.0',
+                               '9e2d2c1cc09d2a40eeb72e8c5db789e3b9bf2586',
+                               configure='')
+
+    def build(self):
+        self.sh('%{make} update_submodules')
+        self.sh('%{make} PREFIX=%{package_prefix}')
+
+    def install(self):
+        self.sh('%{makeinstall} PREFIX=%{staged_prefix}')
+
+NuGetPackage()
diff --git a/packaging/MacSDK/packaging/Info.plist b/packaging/MacSDK/packaging/Info.plist
new file mode 100644 (file)
index 0000000..8c3799d
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>CFBundleGetInfoString</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+        <key>CFBundleIdentifier</key>
+        <string>com.ximian.mono-@@MONO_VERSION@@</string>
+        <key>CFBundleName</key>
+        <string>Mono.framework</string>
+        <key>CFBundleShortVersionString</key>
+        <string>@@MONO_VERSION@@</string>
+        <key>IFPkgFlagAllowBackRev</key>
+        <true/>
+        <key>IFPkgFlagAuthorizationAction</key>
+        <string>AdminAuthorization</string>
+        <key>IFPkgFlagDefaultLocation</key>
+        <string>/</string>
+        <key>IFPkgFlagInstallFat</key>
+        <false/>
+        <key>IFPkgFlagIsRequired</key>
+        <false/>
+        <key>IFPkgFlagRelocatable</key>
+        <false/>
+        <key>IFPkgFlagRestartAction</key>
+        <string>NoRestart</string>
+        <key>IFPkgFlagRootVolumeOnly</key>
+        <true/>
+        <key>IFPkgFlagUpdateInstalledLanguages</key>
+        <false/>
+        <key>IFPkgFormatVersion</key>
+        <real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/packaging/MacSDK/packaging/Info_sdk.plist b/packaging/MacSDK/packaging/Info_sdk.plist
new file mode 100644 (file)
index 0000000..7d75b1a
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>CFBundleGetInfoString</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+        <key>CFBundleIdentifier</key>
+        <string>com.ximian.mono-@@MONO_VERSION@@-csdk</string>
+        <key>CFBundleName</key>
+        <string>Mono.framework</string>
+        <key>CFBundleShortVersionString</key>
+        <string>@@MONO_VERSION@@</string>
+        <key>IFPkgFlagAllowBackRev</key>
+        <true/>
+        <key>IFPkgFlagAuthorizationAction</key>
+        <string>AdminAuthorization</string>
+        <key>IFPkgFlagDefaultLocation</key>
+        <string>/</string>
+        <key>IFPkgFlagInstallFat</key>
+        <false/>
+        <key>IFPkgFlagIsRequired</key>
+        <false/>
+        <key>IFPkgFlagRelocatable</key>
+        <false/>
+        <key>IFPkgFlagRestartAction</key>
+        <string>NoRestart</string>
+        <key>IFPkgFlagRootVolumeOnly</key>
+        <true/>
+        <key>IFPkgFlagUpdateInstalledLanguages</key>
+        <false/>
+        <key>IFPkgFormatVersion</key>
+        <real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/packaging/MacSDK/packaging/mdk_blacklist.sh b/packaging/MacSDK/packaging/mdk_blacklist.sh
new file mode 100755 (executable)
index 0000000..ab426a7
--- /dev/null
@@ -0,0 +1,135 @@
+#!/bin/bash
+
+if test x$1 = x; then
+   echo usage is cleanup MONODIR
+   exit 1
+fi
+
+MONODIR=$1
+
+cd $MONODIR
+rm -rf lib/gtk-2.0/2.10.0/engines/libcrux-engine.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libglide.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libhcengine.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libindustrial.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libmist.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libpixmap.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libredmond95.so
+rm -rf lib/gtk-2.0/2.10.0/engines/libthinice.so
+rm -rf gtk-2.0/modules/libferret.*
+rm -rf gtk-2.0/modules/libgail.*
+rm -rf share/gtk-2.0/demo/*
+rm -rf share/man/man1/oldmono.1
+rm -rf share/themes/Crux
+rm -rf share/themes/Default
+rm -rf share/themes/Emacs
+rm -rf share/themes/Industrial
+rm -rf share/themes/Mist
+rm -rf share/themes/Raleigh
+rm -rf share/themes/Redmond
+rm -rf share/themes/ThinIce
+rm -rf share/info
+rm -rf share/icons/gnome
+rm -rf share/icons/hicolor
+rm -rf share/gtk-doc
+rm -rf share/gettext/*.class
+rm -rf share/doc
+rm -rf share/emacs
+rm -rf share/strings
+rm -rf share/pixmaps
+rm -rf share/intltool
+rm -rf var/cache/fontconfig
+
+# delete most of the *.a files
+rm -rf lib/cairo/libcairo-trace.a
+rm -rf lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.a
+rm -rf lib/gtk-2.0/2.10.0/engines/libsvg.a
+rm -rf lib/libCompilerDriver.a
+rm -rf lib/libEnhancedDisassembly.a
+rm -rf lib/libLLVMAnalysis.a
+rm -rf lib/libLLVMArchive.a
+rm -rf lib/libLLVMAsmParser.a
+rm -rf lib/libLLVMAsmPrinter.a
+rm -rf lib/libLLVMBitReader.a
+rm -rf lib/libLLVMBitWriter.a
+rm -rf lib/libLLVMCodeGen.a
+rm -rf lib/libLLVMCore.a
+rm -rf lib/libLLVMExecutionEngine.a
+rm -rf lib/libLLVMInstCombine.a
+rm -rf lib/libLLVMInstrumentation.a
+rm -rf lib/libLLVMInterpreter.a
+rm -rf lib/libLLVMJIT.a
+rm -rf lib/libLLVMLinker.a
+rm -rf lib/libLLVMMC.a
+rm -rf lib/libLLVMMCDisassembler.a
+rm -rf lib/libLLVMMCJIT.a
+rm -rf lib/libLLVMMCParser.a
+rm -rf lib/libLLVMObject.a
+rm -rf lib/libLLVMScalarOpts.a
+rm -rf lib/libLLVMSelectionDAG.a
+rm -rf lib/libLLVMSupport.a
+rm -rf lib/libLLVMTarget.a
+rm -rf lib/libLLVMTransformUtils.a
+rm -rf lib/libLLVMX86AsmParser.a
+rm -rf lib/libLLVMX86AsmPrinter.a
+rm -rf lib/libLLVMX86CodeGen.a
+rm -rf lib/libLLVMX86Disassembler.a
+rm -rf lib/libLLVMX86Info.a
+rm -rf lib/libLLVMipa.a
+rm -rf lib/libLLVMipo.a
+rm -rf lib/libLTO.a
+# rm -rf lib/libMonoPosixHelper.a
+# rm -rf lib/libMonoSupportW.a
+rm -rf lib/libUnitTestMain.a
+rm -rf lib/libatksharpglue-2.a
+rm -rf lib/libcairo-gobject.a
+rm -rf lib/libcairo-script-interpreter.a
+rm -rf lib/libcairo.a
+rm -rf lib/libcroco-0.6.a
+rm -rf lib/libexpat.a
+rm -rf lib/libffi.a
+rm -rf lib/libfontconfig.a
+rm -rf lib/libfreetype.a
+rm -rf lib/libgdiplus.a
+rm -rf lib/libgdksharpglue-2.a
+rm -rf lib/libgettextpo.a
+rm -rf lib/libgif.a
+rm -rf lib/libglade-2.0.a
+rm -rf lib/libgladesharpglue-2.a
+rm -rf lib/libglibsharpglue-2.a
+rm -rf lib/libgtksharpglue-2.a
+rm -rf lib/libikvm-native.a
+rm -rf lib/libintl.a
+rm -rf lib/libjpeg.a
+rm -rf lib/liblzma.a
+# rm -rf lib/libmono-2.0.a
+# rm -rf lib/libmono-llvm.a
+# rm -rf lib/libmono-profiler-aot.a
+# rm -rf lib/libmono-profiler-cov.a
+# rm -rf lib/libmono-profiler-iomap.a
+# rm -rf lib/libmono-profiler-log.a
+# rm -rf lib/libmonosgen-2.0.a
+rm -rf lib/libpangosharpglue-2.a
+rm -rf lib/libpixman-1.a
+rm -rf lib/libpng.a
+rm -rf lib/libpng14.a
+rm -rf lib/librsvg-2.a
+rm -rf lib/libsqlite3.a
+rm -rf lib/libtiff.a
+rm -rf lib/libtiffxx.a
+rm -rf lib/libxml2.a
+
+# we don't need any of the llvm executables except llc and opt
+rm -rf bin/bugpoint
+rm -rf bin/lli
+rm -rf bin/llvm-*
+rm -rf bin/macho-dump
+rm -rf bin/ccache
+
+#
+# 14:39 <baulig> the install script needs to be modified not to
+#                install .mdb's for these
+# 14:39 <baulig> System.Windows.dll, System.Xml.Serialization.dll and
+#                everything in Facades
+
+find ./lib/mono/4.5/Facades -name "*.mdb" -delete
diff --git a/packaging/MacSDK/packaging/resources/License.rtf b/packaging/MacSDK/packaging/resources/License.rtf
new file mode 100644 (file)
index 0000000..ab13fe4
--- /dev/null
@@ -0,0 +1,26 @@
+{\rtf1\mac\ansicpg10000\cocoartf102
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww9000\viewh9000\viewkind0
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 The software included in the package is licensed under several different agreements.\
+\
+MIT License:\
+\
+http://www.opensource.org/licenses/mit-license.php\
+\
+LGPL:\
+\
+http://www.opensource.org/licenses/lgpl-2.1.php\
+\
+GPL:\
+\
+http://www.opensource.org/licenses/gpl-2.0.php\
+\
+You can develop commercial applications and redistribute the code in this package.
+You only need to obtain a commercial license if you wish to make changes to Mono or
+if you are using Mono as an embedded runtime into your application.\
+\
+Contact contact@xamarin.com if you think you need a license.
+}
diff --git a/packaging/MacSDK/packaging/resources/ReadMe.rtf b/packaging/MacSDK/packaging/resources/ReadMe.rtf
new file mode 100644 (file)
index 0000000..704571f
--- /dev/null
@@ -0,0 +1,41 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww15940\viewh15760\viewkind0
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640
+
+\f0\fs24 \cf0 This README is for
+\b  Mono.framework @@MONO_VERSION_RELEASE@@
+\b0 .\
+\
+This is the Mono Runtime and Development Platform (http://www.mono-project.com/).\
+\
+This package installs Mono and all of its dependencies inside of /Library/Frameworks/Mono.framework.  This behavior is likely to change with a future release so that dependancies will get their own frameworks.\
+\
+The following components are included inside Mono.framework:\
+@@PACKAGES@@\
+\
+Other packages used to build Mono.framework:\
+@@DEP_PACKAGES@@\
+If you want to build native Mac applications with Mono, you can use the MonoMac bindings, an add-on to this product available from http://www.mono-project.com/MonoMac\
+\
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
+\cf0 \
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640
+\cf0 \
+\
+A simple uninstallMono.sh script is included in the disk image.  This is shell script that must be run as root, and it will remove the Mono.framework and the links in /usr/bin.\
+\
+This package was created by the Mono team.  Major contributors to this team include (in alphabetical order): \
+\
+Wade Berrier\
+Adhamh Findlay\
+Miguel de Icaza\
+Urs Muff\
+Geoff Norton\
+Andy Satori\
+\
+Questions or problems related directly to the Mono.framework should be addressed to mono-osx@lists.xamarin.com.\
+\
+Questions about Mono should be directed to an appropriate resource that can be found on http://www.mono-project.com/about. \
+}
\ No newline at end of file
diff --git a/packaging/MacSDK/packaging/resources/Welcome.rtf b/packaging/MacSDK/packaging/resources/Welcome.rtf
new file mode 100644 (file)
index 0000000..200bc99
--- /dev/null
@@ -0,0 +1,12 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
+{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww9000\viewh9000\viewkind0
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
+
+\f0\fs32 \cf0 Welcome to
+\b Mono.framework @@MONO_VERSION_RELEASE@@
+\b0  for OS X.
+\fs36 \
+\
+}
\ No newline at end of file
diff --git a/packaging/MacSDK/packaging/resources/distribution.xml b/packaging/MacSDK/packaging/resources/distribution.xml
new file mode 100644 (file)
index 0000000..39926f9
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<installer-gui-script minSpecVersion="1">
+    <title>Mono Framework</title>
+    <license file="License.rtf" mime-type="application/rtf" />
+    <readme file="ReadMe.rtf" mime-type="application/rtf" />
+    <pkg-ref id="mono">
+        <bundle-version/>
+    </pkg-ref>
+    <choices-outline>
+        <line choice="default">
+            <line choice="mono"/>
+        </line>
+    </choices-outline>
+    <choice id="default"/>
+    <choice id="mono" visible="false">
+        <pkg-ref id="mono"/>
+    </choice>
+    <pkg-ref id="mono">#mono.pkg</pkg-ref>
+</installer-gui-script>
diff --git a/packaging/MacSDK/packaging/resources/postinstall b/packaging/MacSDK/packaging/resources/postinstall
new file mode 100755 (executable)
index 0000000..5ad19ad
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/sh -x
+
+FW=/Library/Frameworks/Mono.framework
+FW_CURRENT=${FW}/Versions/Current
+CURRENT=`basename $(readlink ${FW_CURRENT})`
+
+# Remove PCL assemblies that we installed from Mono 3.1.1
+LICENSE="Portable Class Library Reference Assemblies License-07JUN2013.docx"
+if [ -f "$FW/External/xbuild-frameworks/.NETPortable/$LICENSE" ]; then
+    echo "Removing PCL because we're upgrading from 3.1.1" >> /tmp/mono-installation
+    rm -rf $FW/External/xbuild-frameworks/.NETPortable
+fi
+
+# Remove /usr/local/bin/pkg-config if it's a symlink to the Mono-installed one
+PKG_CONFIG_LINK="/usr/local/bin/pkg-config"
+if [ -L $PKG_CONFIG_LINK ]; then
+    location=`readlink $PKG_CONFIG_LINK`
+    case "$location" in
+    *Mono.framework*) rm $PKG_CONFIG_LINK;;
+    esac
+fi
+
+WHITELIST=$(cat "$(dirname "$0")/whitelist.txt")
+MONO_COMMANDS_FILE=/etc/paths.d/mono-commands
+FW_WHITELISTED_COMMANDS=${FW_CURRENT}/Commands
+
+mkdir ${FW_WHITELISTED_COMMANDS}
+mkdir /etc/paths.d
+
+if test -e ${MONO_COMMANDS_FILE}; then
+    rm "${MONO_COMMANDS_FILE}"
+fi
+
+echo "${FW_WHITELISTED_COMMANDS}" >> "${MONO_COMMANDS_FILE}"
+
+if [ -d "${FW}"/Commands ]; then
+    for i in ${WHITELIST}; do
+        if test -e "${FW}/Commands/${i}"; then
+            ln -s "${FW}/Commands/${i}" "${FW_WHITELISTED_COMMANDS}/${i}"
+        fi
+    done;
+else
+    echo "${FW}/Commands does not exist"
+    echo "Can not add command links to $PATH."
+fi
+
+if [ -d ${FW_CURRENT} ]; then
+    cd ${FW_CURRENT}/share/man
+    for i in ${WHITELIST}; do
+        for j in $(ls man*/${i}.*); do
+            if test ! -e "/usr/local/share/man/${j}"; then
+                ln -sf "${FW_CURRENT}/share/man/${j}" "/usr/local/share/man/${j}"
+            fi
+        done
+    done
+
+    cd ${FW_CURRENT}/etc
+    # Make sure we run the files we lay down, and not other stuff installed on the system
+    export PATH=${FW_CURRENT}/bin:$PATH
+    # gtk+ setup
+    gdk-pixbuf-query-loaders --update-cache
+    # pango setup
+    mkdir -p pango
+    pango-querymodules >  pango/pango.modules
+    pango-querymodules --update-cache
+    fc-cache
+
+    cd ${FW_CURRENT}/lib/gtk-2.0/2.10.0
+    gtk-query-immodules-2.0 > immodules.cache
+fi
+
+# Delete older Monos
+#
+# - keep if the major version is different
+# - keep if 'Versions/x.y.z/keep' exists
+# - Keep if it is greater than $CURRENT
+#
+echo "Current:" $CURRENT >> /tmp/mono-installation
+
+pushd ${FW}/Versions
+for i in `ls -d *`; do
+    result=`echo "${i:0:1} == ${CURRENT:0:1}" | bc`
+    if [ $result -ne 1 ]; then
+        echo "keeping" $i "because it has a different major version" >> /tmp/mono-installation
+        continue
+    fi
+
+    if [ -f $i/keep ]; then
+        echo "Keeping" $i "because of keep file" >> /tmp/mono-installation
+        continue
+    fi
+
+    # A magical bit of Perl: http://stackoverflow.com/a/7366753/494990
+    result=$(perl -e '($a,$b)=@ARGV; for ($a,$b) {s/(\d+)/sprintf "%5d", $1/ge}; print $a cmp $b;' $i $CURRENT)
+    if [ $result -ge 0 ]; then
+        echo "Skipping" $i "because $i >= $CURRENT" >> /tmp/mono-installation
+        continue
+
+    else
+        echo "rm -rf" $i >> /tmp/mono-installation
+        rm -rf $i
+    fi
+done
+popd
+
+# Mono framework should be owned by root
+chown -R root:admin ${FW}
diff --git a/packaging/MacSDK/packaging/resources/version.plist b/packaging/MacSDK/packaging/resources/version.plist
new file mode 100644 (file)
index 0000000..df2e67c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>BuildVersion</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+        <key>CFBundleShortVersionString</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+        <key>CFBundleVersion</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+        <key>ProjectName</key>
+        <string>Mono</string>
+        <key>SourceVersion</key>
+        <string>@@MONO_VERSION_RELEASE@@</string>
+</dict>
+</plist>
diff --git a/packaging/MacSDK/packaging/resources/whitelist.txt b/packaging/MacSDK/packaging/resources/whitelist.txt
new file mode 100644 (file)
index 0000000..7d329a9
--- /dev/null
@@ -0,0 +1,129 @@
+al
+al2
+asp-state
+asp-state2
+asp-state4
+booc
+booi
+booish
+caspol
+ccrewrite
+cccheck
+cert2spc
+certmgr
+chktrust
+ClassInitGenerator
+csharp
+csharp2
+dbsessmgr
+dbsessmgr2
+dbsessmgr4
+disco
+dmcs
+dtd2rng
+dtd2xsd
+fastcgi-mono-server
+fastcgi-mono-server2
+fastcgi-mono-server4
+fsharpc
+fsharpc2
+fsharpi
+fsharpi2
+gacutil
+gacutil2
+gapi2-codegen
+gapi2-fixup
+gapi2-parser
+genxs
+gmcs
+httpcfg
+ikdasm
+ilasm
+installvst
+ipy
+ipy64
+ipyw
+ipyw64
+ir
+ir64
+IronRuby.Tests
+irw
+irw64
+lc
+macpack
+makecert
+mautil
+mconfig
+mcs
+mdassembler
+mdoc
+mdoc-assemble
+mdoc-export-html
+mdoc-export-msxdoc
+mdoc-update
+mdoc-validate
+mdvalidater
+mkbundle
+mod
+mod-mono-server
+mod-mono-server2
+mod-mono-server4
+mono
+mono64
+mono-boehm
+mono-api-info
+mono-api-html
+mono-cil-strip
+mono-configuration-crypto
+monodis
+monodocer
+monodocs2html
+monodocs2slashdoc
+mono-find-provides
+mono-find-requires
+mono-gdb.py
+monograph
+mono-heapviz
+monolinker
+monop
+monop2
+mono-service
+mono-service2
+mono-sgen
+mono-shlib-cop
+mono-symbolicate
+mono-test-install
+mono-xmltool
+mozroots
+mprof-report
+msbuild
+nant
+nuget
+nunit-console
+nunit-console2
+nunit-console4
+pdb2mdb
+pedump
+permview
+peverify
+prj2make
+resgen
+resgen2
+secutil
+setreg
+sgen
+signcode
+sn
+soapsuds
+sqlmetal
+sqlsharp
+svcutil
+vbnc
+vbnc2
+wsdl
+wsdl2
+xbuild
+xsd
+xsp
+xsp2
+xsp4
diff --git a/packaging/MacSDK/packaging/uninstallMono.sh b/packaging/MacSDK/packaging/uninstallMono.sh
new file mode 100755 (executable)
index 0000000..9e88ad1
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh -x
+
+#This script removes Mono from an OS X System.  It must be run as root
+
+rm -r /Library/Frameworks/Mono.framework
+
+# In 10.6+ the receipts are stored here
+rm /var/db/receipts/com.ximian.mono*
+
+for dir in /usr/local/bin; do
+   (cd ${dir};
+    for i in `ls -al | grep /Library/Frameworks/Mono.framework/ | awk '{print $9}'`; do
+      rm ${i}
+    done);
+done
diff --git a/packaging/MacSDK/patches/find-unused-patches.sh b/packaging/MacSDK/patches/find-unused-patches.sh
new file mode 100755 (executable)
index 0000000..b758c97
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+for f in *.patch; do grep $f ../*.py > /dev/null || echo $f; done
+for f in */*.patch; do grep $f ../*.py > /dev/null || echo $f; done
diff --git a/packaging/MacSDK/patches/mcs-pkgconfig.patch b/packaging/MacSDK/patches/mcs-pkgconfig.patch
new file mode 100644 (file)
index 0000000..eeefebc
--- /dev/null
@@ -0,0 +1,23 @@
+diff --git a/scripts/Makefile.am b/scripts/Makefile.am
+index 73b9cea..98b8cfb 100644
+--- a/scripts/Makefile.am
++++ b/scripts/Makefile.am
+@@ -179,7 +179,8 @@ REWRITE_COMMON = sed \
+       -e 's,@''bindir@,$(bindir),g'                           \
+       -e 's,@''plat_bindir@,$(plat_bindir),g'                 \
+       -e 's,@''mono_instdir@,$(mono_instdir),g'               \
+-      -e 's,@''gtkdir@,$(gtkdir),g'
++      -e 's,@''gtkdir@,$(gtkdir),g'                           \
++      -e 's,@''mono_version@,$(VERSION),g'
+
+ REWRITE = $(REWRITE_COMMON) -e 's,@''mono_interp@,$(mono_interp),g'
+ REWRITE_DEBUG = $(REWRITE_COMMON) -e 's,@''mono_interp@,$(mono_interp) --debug,g'
+diff --git a/scripts/mcs.in b/scripts/mcs.in
+index 32498fa..c15087e 100644
+--- a/scripts/mcs.in
++++ b/scripts/mcs.in
+@@ -1,2 +1,4 @@
+ #!/bin/sh
++export PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/@mono_version@/bin
++export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/External/pkgconfig:/Library/Frameworks/Mono.framework/Versions/@mono_version@/lib/pkgconfig:/Library/Frameworks/Mono.framework/Versions/@mono_version@/share/pkgconfig:$PKG_CONFIG_PATH
+ exec @bindir@/mono $MONO_OPTIONS @mono_instdir@/2.0/mcs.exe -lib:@mono_instdir@/2.0 -lib:@mono_instdir@/3.5 "$@"
diff --git a/packaging/MacSDK/pcl-reference-assemblies.py b/packaging/MacSDK/pcl-reference-assemblies.py
new file mode 100644 (file)
index 0000000..216e9f7
--- /dev/null
@@ -0,0 +1,57 @@
+import glob
+import os
+import shutil
+
+
+class PCLReferenceAssembliesPackage(Package):
+
+    def __init__(self):
+        Package.__init__(self,
+                         name='PortableReferenceAssemblies',
+                         version='2014-04-14',
+                         sources=['http://xamarin-storage/bot-provisioning/PortableReferenceAssemblies-2014-04-14.zip'])
+
+    def build(self):
+        pass
+
+    # A bunch of shell script written inside python literals ;(
+    def install(self):
+        dest = os.path.join(
+            self.staged_prefix,
+            "lib",
+            "mono",
+            "xbuild-frameworks",
+            ".NETPortable")
+        if not os.path.exists(dest):
+            os.makedirs(dest)
+
+        shutil.rmtree(dest, ignore_errors=True)
+
+        self.sh("rsync -abv -q %s/* %s" % (self.workspace, dest))
+
+        for f in glob.glob("%s/*/Profile/*/SupportedFrameworks" % dest):
+            self.write_xml(f)
+
+    def write_xml(self, directory):
+        # print "Writing iOS/Android/Mac listings for " + directory
+        data = {
+            os.path.join(directory, "MonoTouch.xml"):
+            """<Framework Identifier="MonoTouch" MinimumVersion="1.0" Profile="*" DisplayName="Xamarin.iOS Classic"/>""",
+            os.path.join(directory, "Xamarin.iOS.xml"):
+            """<Framework Identifier="Xamarin.iOS" MinimumVersion="1.0" Profile="*" DisplayName="Xamarin.iOS Unified"/>""",
+            os.path.join(directory, "Xamarin.Android.xml"):
+            """<Framework Identifier="MonoAndroid" MinimumVersion="1.0" Profile="*" DisplayName="Xamarin.Android"/>""",
+            os.path.join(directory, "Xamarin.Mac.xml"):
+            """<Framework Identifier="Xamarin.Mac" MinimumVersion="2.0" Profile="*" DisplayName="Xamarin.Mac Unified"/>""",
+            os.path.join(directory, "Xamarin.TVOS.xml"):
+            """<Framework Identifier="Xamarin.TVOS" MinimumVersion="1.0" Profile="*" DisplayName="Xamarin.TVOS"/>""",
+            os.path.join(directory, "Xamarin.WatchOS.xml"):
+            """<Framework Identifier="Xamarin.WatchOS" MinimumVersion="1.0" Profile="*" DisplayName="Xamarin.WatchOS"/>""",
+        }
+        for filename, content in data.iteritems():
+            f = open(filename, "w")
+            f.write(content + "\n")
+            f.close()
+
+
+PCLReferenceAssembliesPackage()
diff --git a/packaging/MacSDK/profile.py b/packaging/MacSDK/profile.py
new file mode 100755 (executable)
index 0000000..1a7827d
--- /dev/null
@@ -0,0 +1,394 @@
+import itertools
+import os
+import re
+import shutil
+import string
+import sys
+import tempfile
+import subprocess
+import stat
+
+from bockbuild.darwinprofile import DarwinProfile
+from bockbuild.util.util import *
+from glob import glob
+
+class MonoReleaseProfile(DarwinProfile):
+    description = 'The Mono Framework for MacOS'
+    packages = [
+        'gettext',
+        'pkg-config',
+
+        # Base Libraries
+        'libpng',
+        'libjpeg',
+        'libtiff',
+        'libgif',
+        'libxml2',
+        'freetype',
+        'fontconfig',
+        'pixman',
+        'cairo',
+        'libffi',
+        'glib',
+        'pango',
+        'atk',
+        'intltool',
+        'gdk-pixbuf',
+        'gtk+',
+        'libglade',
+        'sqlite',
+        'expat',
+        'ige-mac-integration',
+
+        # Theme
+        'libcroco',
+        'librsvg',
+        'hicolor-icon-theme',
+        'gtk-engines',
+        'murrine',
+        'xamarin-gtk-theme',
+        'gtk-quartz-engine',
+
+        # Mono
+        'mono-llvm',
+        'mono',
+        'msbuild',
+        'pcl-reference-assemblies',
+        'libgdiplus',
+        'xsp',
+        'gtk-sharp',
+        'ironlangs',
+        'fsharp',
+        'mono-basic',
+        'nuget'
+    ]
+
+    def attach (self, bockbuild):
+        self.min_version = 7
+        DarwinProfile.attach (self, bockbuild)
+
+        # quick disk space check (http://stackoverflow.com/questions/787776/)
+        s = os.statvfs(bockbuild.root)
+        free_space = (s.f_bavail * s.f_frsize) / (1024 * 1024 * 1024)  # in GB
+
+        if free_space < 10:
+            error('Low disk space (less than 10GB), aborting')
+
+        # check for XQuartz installation (needed for libgdiplus)
+        if not os.path.exists('/opt/X11/include/X11/Xlib.h'):
+            error(
+                'XQuartz is required to be installed (download from http://xquartz.macosforge.org/) ')
+
+        self.MONO_ROOT = "/Library/Frameworks/Mono.framework"
+        self.BUILD_NUMBER = "0"
+        self.MDK_GUID = "964ebddd-1ffe-47e7-8128-5ce17ffffb05"
+
+        system_mono_dir = '/Library/Frameworks/Mono.framework/Versions/Current'
+        self.env.set('system_mono', os.path.join(
+            system_mono_dir, 'bin', 'mono'))
+        self.env.set('system_mcs', os.path.join(system_mono_dir, 'bin', 'mcs'))
+
+        self.env.set('system_mono_version', backtick(
+            '%s --version' % self.env.system_mono)[0])
+
+        # config overrides for some programs to be functional while staged
+
+        self.env.set('GDK_PIXBUF_MODULE_FILE',
+                     '%{staged_prefix}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache')
+        self.env.set('GDK_PIXBUF_MODULEDIR',
+                     '%{staged_prefix}/lib/gdk-pixbuf-2.0/2.10.0/loaders')
+        self.env.set('PANGO_SYSCONFDIR', '%{staged_prefix}/etc')
+        self.env.set('PANGO_LIBDIR', '%{staged_prefix}/lib')
+        # self.env.set ('MONO_PATH', '%{staged_prefix}/lib/mono/4.0')
+        self.debug_info = ['gtk+', 'cairo',
+                           'pango', 'mono', 'llvm', 'libgdiplus']
+        self.cache_host = None
+
+    def setup_release(self):
+        self.mono_package = self.release_packages['mono']
+        self.mono_package.fetch()
+
+        verbose('Mono version: %s' % self.mono_package.version)
+        self.RELEASE_VERSION = self.mono_package.version
+        self.prefix = os.path.join(
+            self.MONO_ROOT, "Versions", self.RELEASE_VERSION)
+
+        if os.path.exists(self.prefix):
+            error('Prefix %s exists, and may interfere with the staged build. Please remove and try again.' % self.prefix)
+
+        self.calculate_updateid()
+        trace(self.package_info('MDK'))
+
+        self.dont_optimize = ['pixman']
+
+        for p in self.release_packages.values():
+            if p.name in self.dont_optimize:
+                continue
+            self.gcc_flags.extend(['-O2'])
+
+    # THIS IS THE MAIN METHOD FOR MAKING A PACKAGE
+    def package(self):
+        self.fix_gtksharp_configs()
+        self.verify_binaries()
+
+        working = self.setup_working_dir()
+        uninstall_script = os.path.join(working, "uninstallMono.sh")
+
+        # make the MDK
+        self.apply_blacklist(working, 'mdk_blacklist.sh')
+        self.make_updateinfo(working, self.MDK_GUID)
+        mdk_pkg = self.run_pkgbuild(working, "MDK")
+        title(mdk_pkg)
+        # self.make_dmg(mdk_dmg, title, mdk_pkg, uninstall_script)
+
+        shutil.rmtree(working)
+
+    def calculate_updateid(self):
+        # Create the updateid
+        pwd = os.getcwd()
+        git_bin = self.bockbuild.git_bin
+        trace("cur path is %s and git is %s" % (pwd, git_bin))
+        blame_rev_str = 'cd %s; %s blame configure.ac HEAD | grep AC_INIT | sed \'s/ .*//\' ' % (
+            self.mono_package.workspace, git_bin)
+        blame_rev = backtick(blame_rev_str)[0]
+        trace("Last commit to the version string %s" % (blame_rev))
+        version_number_str = 'cd %s; %s log %s..HEAD --oneline | wc -l | sed \'s/ //g\'' % (
+            self.mono_package.workspace, git_bin, blame_rev)
+        self.BUILD_NUMBER = backtick(version_number_str)[0]
+        trace("Calculating commit distance, %s" % (self.BUILD_NUMBER))
+        self.FULL_VERSION = self.RELEASE_VERSION + "." + self.BUILD_NUMBER
+        os.chdir(pwd)
+
+        parts = self.RELEASE_VERSION.split(".")
+        version_list = (parts + ["0"] * (3 - len(parts)))[:4]
+        for i in range(1, 3):
+            version_list[i] = version_list[i].zfill(2)
+            self.updateid = "".join(version_list)
+            self.updateid += self.BUILD_NUMBER.replace(
+                ".", "").zfill(9 - len(self.updateid))
+        trace(self.updateid)
+
+    # creates and returns the path to a working directory containing:
+    #   PKGROOT/ - this root will be bundled into the .pkg and extracted at /
+    #   uninstallMono.sh - copied onto the DMG
+    #   Info{_sdk}.plist - used by packagemaker to make the installer
+    #   resources/ - other resources used by packagemaker for the installer
+    def setup_working_dir(self):
+        def make_package_symlinks(root):
+            os.symlink(self.prefix, os.path.join(root, "Versions", "Current"))
+            currentlink = os.path.join(self.MONO_ROOT, "Versions", "Current")
+            links = [
+                ("bin", "Commands"),
+                ("include", "Headers"),
+                ("lib", "Libraries"),
+                ("", "Home"),
+                (os.path.join("lib", "libmono-2.0.dylib"), "Mono")
+            ]
+            for srcname, destname in links:
+                src = os.path.join(currentlink, srcname)
+                dest = os.path.join(root, destname)
+                # If the symlink exists, we remove it so we can create a fresh
+                # one
+                if os.path.exists(dest):
+                    os.unlink(dest)
+                os.symlink(src, dest)
+
+        tmpdir = tempfile.mkdtemp()
+        monoroot = os.path.join(tmpdir, "PKGROOT", self.MONO_ROOT[1:])
+        versions = os.path.join(monoroot, "Versions")
+        os.makedirs(versions)
+
+        print "Setting up temporary package directory:", tmpdir
+
+        # setup metadata
+        self.packaging_dir = os.path.join(self.resource_path, "packaging")
+        run_shell('rsync -aPq %s/* %s' % (self.packaging_dir, tmpdir), False)
+
+        packages_list = string.join(
+            [pkg.desc for pkg in self.release_packages.values()], "\\\n")
+        deps_list = 'bockbuild (rev. %s)\\\n' % bockbuild.bockbuild_rev + string.join(
+            [pkg.desc for pkg in self.toolchain_packages.values()], "\\\n")
+
+        parameter_map = {
+            '@@MONO_VERSION@@': self.RELEASE_VERSION,
+            '@@MONO_RELEASE@@': self.BUILD_NUMBER,
+            '@@MONO_VERSION_RELEASE@@': self.RELEASE_VERSION + '_' + self.BUILD_NUMBER,
+            '@@MONO_CSDK_GUID@@': self.MDK_GUID,
+            '@@MONO_VERSION_RELEASE_INT@@': self.updateid,
+            '@@PACKAGES@@': packages_list,
+            '@@DEP_PACKAGES@@': deps_list
+        }
+        for dirpath, d, files in os.walk(tmpdir):
+            for name in files:
+                if not name.startswith('.'):
+                    replace_in_file(os.path.join(dirpath, name), parameter_map)
+
+        make_package_symlinks(monoroot)
+
+        # copy to package root
+        run_shell('rsync -aPq "%s"/* "%s/%s"' %
+                  (bockbuild.package_root, versions, self.RELEASE_VERSION), False)
+
+        return tmpdir
+
+    def apply_blacklist(self, working_dir, blacklist_name):
+        print "Applying blacklist script:", blacklist_name
+        blacklist = os.path.join(self.packaging_dir, blacklist_name)
+        root = os.path.join(working_dir, "PKGROOT", self.prefix[1:])
+        run_shell('%s "%s" > /dev/null' % (blacklist, root), print_cmd=False)
+
+    def run_pkgbuild(self, working_dir, package_type):
+        print 'Running pkgbuild & productbuild...',
+        info = self.package_info(package_type)
+        output = os.path.join(self.resource_path, info["filename"])
+        identifier = "com.xamarin.mono-" + info["type"] + ".pkg"
+        resources_dir = os.path.join(working_dir, "resources")
+        distribution_xml = os.path.join(resources_dir, "distribution.xml")
+
+        old_cwd = os.getcwd()
+        os.chdir(working_dir)
+        pkgbuild = "/usr/bin/pkgbuild"
+        pkgbuild_cmd = ' '.join([pkgbuild,
+                                 "--identifier " + identifier,
+                                 "--root '%s/PKGROOT'" % working_dir,
+                                 "--version '%s'" % self.RELEASE_VERSION,
+                                 "--install-location '/'",
+                                 "--scripts '%s'" % resources_dir,
+                                 "--quiet",
+                                 os.path.join(working_dir, "mono.pkg")])
+
+        run_shell(pkgbuild_cmd)
+
+        productbuild = "/usr/bin/productbuild"
+        productbuild_cmd = ' '.join([productbuild,
+                                     "--resources %s" % resources_dir,
+                                     "--distribution %s" % distribution_xml,
+                                     "--package-path %s" % working_dir,
+                                     "--quiet",
+                                     output])
+
+        run_shell(productbuild_cmd)
+
+        assert_exists(output)
+        os.chdir(old_cwd)
+        print output
+        return output
+
+    def make_updateinfo(self, working_dir, guid):
+        updateinfo = os.path.join(
+            working_dir, "PKGROOT", self.prefix[1:], "updateinfo")
+        with open(updateinfo, "w") as updateinfo:
+            updateinfo.write(guid + ' ' + self.updateid + "\n")
+
+    def package_info(self, pkg_type):
+        arch = self.bockbuild.cmd_options.arch
+        arch_str = None
+        if  arch == "darwin-32":
+            arch_str = "x86"
+        elif arch == "darwin-64":
+            arch_str = "x64"
+        elif arch == "darwin-universal":
+            arch_str = "universal"
+        else:
+            error ("Unknown architecture")
+
+        if self.bockbuild.cmd_options.release_build:
+            info = (pkg_type, self.FULL_VERSION, arch_str)
+        else:
+            info = (pkg_type, '%s-%s' % (git_shortid(self.bockbuild,
+                                                     self.mono_package.workspace), self.FULL_VERSION), arch_str)
+
+        filename = "MonoFramework-%s-%s.macos10.xamarin.%s.pkg" % info
+        return {
+            "type": pkg_type,
+            "filename": filename
+        }
+
+    def fix_line(self, line, matcher):
+        def insert_install_root(matches):
+            root = self.prefix
+            captures = matches.groupdict()
+            return 'target="%s"' % os.path.join(root, "lib", captures["lib"])
+
+        if matcher(line):
+            pattern = r'target="(?P<lib>.+\.dylib)"'
+            result = re.sub(pattern, insert_install_root, line)
+            return result
+        else:
+            return line
+
+    def fix_dllmap(self, config, matcher):
+        handle, temp = tempfile.mkstemp()
+        with open(config) as c:
+            with open(temp, "w") as output:
+                for line in c:
+                    output.write(self.fix_line(line, matcher))
+        os.rename(temp, config)
+        os.system('chmod a+r %s' % config)
+
+    def fix_gtksharp_configs(self):
+        print 'Fixing GTK# configuration files...',
+        count = 0
+        libs = [
+            'atk-sharp',
+            'gdk-sharp',
+            'glade-sharp',
+            'glib-sharp',
+            'gtk-dotnet',
+            'gtk-sharp',
+            'pango-sharp'
+        ]
+        gac = os.path.join(bockbuild.package_root, "lib", "mono", "gac")
+        confs = [glob.glob(os.path.join(gac, x, "*", "*.dll.config")) for x in libs]
+        for c in itertools.chain(*confs):
+            count = count + 1
+            self.fix_dllmap(c, lambda line: "dllmap" in line)
+        print count
+
+    def verify(self, f):
+        result = " ".join(backtick("otool -L " + f))
+        regex = os.path.join(self.MONO_ROOT, "Versions", r"(\d+\.\d+\.\d+)")
+
+        match = re.search(regex, result)
+        if match is None:
+            return
+        token = match.group(1)
+        trace(token)
+        if self.RELEASE_VERSION not in token:
+            raise Exception("%s references Mono %s\n%s" % (f, token, text))
+
+    def verify_binaries(self):
+        bindir = os.path.join(bockbuild.package_root, "bin")
+        for path, dirs, files in os.walk(bindir):
+            for name in files:
+                f = os.path.join(path, name)
+                file_type = backtick('file "%s"' % f)
+                if "Mach-O executable" in "".join(file_type):
+                    self.verify(f)
+
+    def shell(self):
+        envscript = '''#!/bin/sh
+        PROFNAME="%s"
+        INSTALLDIR="%s"
+        ROOT="%s"
+        export DYLD_FALLBACK_LIBRARY_PATH="$INSTALLDIR/lib:/lib:/usr/lib"
+        export ACLOCAL_PATH="$INSTALLDIR/share/aclocal"
+        export CONFIG_SITE="$INSTALLDIR/$PROFNAME-config.site"
+        export MONO_GAC_PREFIX="$INSTALLDIR"
+        export MONO_ADDINS_REGISTRY="$ROOT/addinreg"
+        export MONO_INSTALL_PREFIX="$INSTALLDIR"
+
+        export PS1="\[\e[1;3m\][$PROFNAME] \w @ "
+        bash -i
+        ''' % (self.profile_name, self.staged_prefix, self.root)
+
+        path = os.path.join(self.root, self.profile_name + '.sh')
+
+        with open(path, 'w') as f:
+            f.write(envscript)
+
+        os.chmod(path, os.stat(path).st_mode | stat.S_IEXEC)
+
+        subprocess.call(['bash', '-c', path])
+
+MonoReleaseProfile()
\ No newline at end of file
diff --git a/packaging/MacSDK/sqlite.py b/packaging/MacSDK/sqlite.py
new file mode 100644 (file)
index 0000000..f0f5082
--- /dev/null
@@ -0,0 +1,3 @@
+Package('sqlite-autoconf', '3090200', sources=[
+    'http://www.sqlite.org/2015/%{name}-%{version}.tar.gz'
+])
diff --git a/packaging/MacSDK/xamarin-gtk-theme.py b/packaging/MacSDK/xamarin-gtk-theme.py
new file mode 100644 (file)
index 0000000..34d3ae0
--- /dev/null
@@ -0,0 +1,20 @@
+class XamarinGtkThemePackage (Package):
+
+    def __init__(self):
+        Package.__init__(self, 'xamarin-gtk-theme',
+                         sources=[
+                             'git://github.com/mono/xamarin-gtk-theme.git'],
+                         revision='cc3fb66e56d494e968be3a529a0737a60e31c1f3')
+
+    def build(self):
+        try:
+            self.sh('./autogen.sh --prefix=%{staged_prefix}')
+        except:
+            pass
+        finally:
+            #self.sh ('intltoolize --force --copy --debug')
+            #self.sh ('./configure --prefix="%{package_prefix}"')
+            Package.build(self)
+
+
+XamarinGtkThemePackage()
diff --git a/packaging/MacSDK/xsp.py b/packaging/MacSDK/xsp.py
new file mode 100644 (file)
index 0000000..8180001
--- /dev/null
@@ -0,0 +1,23 @@
+class XspPackage (GitHubTarballPackage):
+
+    def __init__(self):
+        GitHubTarballPackage.__init__(self, 'mono', 'xsp', '4.4',
+                                      'c98e068f5647fb06ff2fbef7cd5f1b35417362b1',
+                                      configure='./autogen.sh --prefix="%{package_prefix}"')
+
+    def install(self):
+        # scoop up some mislocated files
+        misdir = '%s%s' % (self.stage_root, self.staged_profile)
+        unprotect_dir(self.stage_root)
+        Package.install(self)
+        if not os.path.exists(misdir):
+            for path in iterate_dir(self.stage_root):
+                print path
+            error('Could not find mislocated files')
+
+        self.sh('rsync -a --ignore-existing %s/* %s' %
+                (misdir, self.profile.staged_prefix))
+        self.sh('rm -rf %s/*' % misdir)
+
+
+XspPackage()
diff --git a/packaging/MacSDKRelease/mono-extensions.py b/packaging/MacSDKRelease/mono-extensions.py
new file mode 100644 (file)
index 0000000..2d52fda
--- /dev/null
@@ -0,0 +1,25 @@
+from bockbuild.package import Package
+
+
+class MonoExtensionsPackage(Package):
+
+    def __init__(self):
+        Package.__init__(self, 'mono-extensions', None,
+                         sources=['git@github.com:xamarin/mono-extensions.git'],
+                         git_branch=self.profile.release_packages[
+                             'mono'].git_branch
+                         )
+        self.source_dir_name = 'mono-extensions'
+
+        # Mono pull requests won't have mono-extensions branches
+        if not self.git_branch or 'pull/' in self.git_branch:
+            warn('Using master branch for mono_extensions')
+            self.git_branch = 'master'
+
+    def build(self):
+        pass
+
+    def install(self):
+        pass
+
+MonoExtensionsPackage()
diff --git a/packaging/MacSDKRelease/packaging b/packaging/MacSDKRelease/packaging
new file mode 120000 (symlink)
index 0000000..714bc29
--- /dev/null
@@ -0,0 +1 @@
+../MacSDK/packaging
\ No newline at end of file
diff --git a/packaging/MacSDKRelease/profile.py b/packaging/MacSDKRelease/profile.py
new file mode 100755 (executable)
index 0000000..2b0d99a
--- /dev/null
@@ -0,0 +1,89 @@
+import itertools
+import os
+import re
+import shutil
+import string
+import sys
+import tempfile
+import traceback
+
+from glob import glob
+
+from MacSDK import profile
+from bockbuild.util.util import *
+
+
+class MonoXamarinPackageProfile(MonoReleaseProfile):
+    description = 'The Mono Framework for MacOS (official release)'
+
+    def setup (self):
+        MonoReleaseProfile.setup (self)
+        bockbuild.packages_to_build.extend(['mono-extensions'])
+        if bockbuild.cmd_options.release_build:
+            self.setup_codesign()
+        else:
+            info("'--release' option not set, will not attempt to sign package!")
+
+        self.cache_host = 'http://xamarin-storage/bockbuild_cache/'
+
+    def setup_codesign(self):
+        self.identity = "Developer ID Installer: Xamarin Inc"
+
+        output = backtick("security -v find-identity")
+        if self.identity not in " ".join(output):
+            error("Identity '%s' was not found. You can create an unsigned package by removing '--release' to your command line." % self.identity)
+
+        password = os.getenv("CODESIGN_KEYCHAIN_PASSWORD")
+        if password:
+            print "Unlocking the keychain"
+            run_shell("security unlock-keychain -p %s" % password)
+        else:
+            error("CODESIGN_KEYCHAIN_PASSWORD needs to be defined.")
+
+    def setup_release(self):
+        MonoReleaseProfile.setup_release(self)
+        self.release_packages['mono'].configure_flags.extend(
+            ['--enable-extension-module=xamarin --enable-native-types --enable-pecrypt'])
+        info('Xamarin extensions enabled')
+
+    def run_pkgbuild(self, working_dir, package_type):
+        output = MonoReleaseProfile.run_pkgbuild(
+            self, working_dir, package_type)
+
+        output_unsigned = os.path.join(os.path.dirname(
+            output), os.path.basename(output).replace('.pkg', '.UNSIGNED.pkg'))
+        shutil.move(output, output_unsigned)
+
+        if not bockbuild.cmd_options.release_build:
+            return output_unsigned
+
+        productsign = "/usr/bin/productsign"
+        productsign_cmd = ' '.join([productsign,
+                                    "-s '%s'" % self.identity,
+                                    "'%s'" % output_unsigned,
+                                    "'%s'" % output])
+        run_shell(productsign_cmd)
+        os.remove(output_unsigned)
+        self.verify_codesign(output)
+
+        return output
+
+    def verify_codesign(self, pkg):
+        oldcwd = os.getcwd()
+        try:
+            name = os.path.basename(pkg)
+            pkgdir = os.path.dirname(pkg)
+            os.chdir(pkgdir)
+            spctl = "/usr/sbin/spctl"
+            spctl_cmd = ' '.join(
+                [spctl, "-vvv", "--assess", "--type install", name, "2>&1"])
+            output = backtick(spctl_cmd)
+
+            if "accepted" in " ".join(output):
+                warn("%s IS SIGNED" % pkg)
+            else:
+                error("%s IS NOT SIGNED:" % pkg)
+        finally:
+            os.chdir(oldcwd)
+
+MonoXamarinPackageProfile()
\ No newline at end of file
index 91c9b11c9c5b1d751a2660da205ff0080118ee9d..a531d8002ef29d812ce51b1748de2ac10438b465 100755 (executable)
@@ -32,7 +32,7 @@ ${TESTCMD} --label=System.Runtime.SFS --timeout=5m make -w -C mcs/class/System.R
 ${TESTCMD} --label=System.Runtime.Remoting --timeout=5m make -w -C mcs/class/System.Runtime.Remoting run-test
 ${TESTCMD} --label=Cscompmgd --timeout=5m make -w -C mcs/class/Cscompmgd run-test;
 ${TESTCMD} --label=Commons.Xml.Relaxng --timeout=5m make -w -C mcs/class/Commons.Xml.Relaxng run-test;
-if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=System.ServiceProcess --skip; else ${TESTCMD} --label=System.ServiceProcess --timeout=5m make -w -C mcs/class/System.ServiceProcess run-test; fi
+${TESTCMD} --label=System.ServiceProcess --timeout=5m make -w -C mcs/class/System.ServiceProcess run-test
 ${TESTCMD} --label=I18N.CJK --timeout=5m make -w -C mcs/class/I18N/CJK run-test
 ${TESTCMD} --label=I18N.West --timeout=5m make -w -C mcs/class/I18N/West run-test
 ${TESTCMD} --label=I18N.MidEast --timeout=5m make -w -C mcs/class/I18N/MidEast run-test
@@ -46,7 +46,7 @@ ${TESTCMD} --label=Mono.Tasklets --timeout=5m make -w -C mcs/class/Mono.Tasklets
 ${TESTCMD} --label=System.Configuration --timeout=5m make -w -C mcs/class/System.Configuration run-test
 ${TESTCMD} --label=System.Transactions --timeout=5m make -w -C mcs/class/System.Transactions run-test
 ${TESTCMD} --label=System.Web.Extensions --timeout=5m make -w -C mcs/class/System.Web.Extensions run-test
-if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=System.Core --skip; else ${TESTCMD} --label=System.Core --timeout=15m make -w -C mcs/class/System.Core run-test; fi
+${TESTCMD} --label=System.Core --timeout=15m make -w -C mcs/class/System.Core run-test
 if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=symbolicate --skip; else ${TESTCMD} --label=symbolicate --timeout=60m make -w -C mcs/tools/mono-symbolicate check; fi
 ${TESTCMD} --label=System.Xml.Linq --timeout=5m make -w -C mcs/class/System.Xml.Linq run-test
 ${TESTCMD} --label=System.Data.DSE --timeout=5m make -w -C mcs/class/System.Data.DataSetExtensions run-test
index b4c6b68c22369b55c3ffcb20899241328b3287f5..0a60dbdc30b8ae7a0373f4db929609644ad4429a 100644 (file)
@@ -1,7 +1,34 @@
-CPPSHARP_DIR = CppSharp
+CPPSHARP_BASE_DIR = CppSharp
+
+ifeq ($(OS),Windows_NT)
+       CPPSHARP_OS=windows
+       ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
+               CPPSHARP_ARCH=64
+       else
+               ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
+                       CPPSHARP_ARCH=64
+               endif
+               ifeq ($(PROCESSOR_ARCHITECTURE),x86)
+                       CPPSHARP_ARCH=32
+               endif
+       endif
+else
+       UNAME_S := $(shell uname -s)
+       ifeq ($(UNAME_S),Linux)
+               CPPSHARP_OS=linux
+               CPPSHARP_ARCH=64
+       endif
+       ifeq ($(UNAME_S),Darwin)
+               CPPSHARP_OS=osx
+               CPPSHARP_ARCH=32
+       endif
+endif
+
+CPPSHARP_DIR = $(CPPSHARP_BASE_DIR)/$(CPPSHARP_OS)_$(CPPSHARP_ARCH)
 
 CPPSHARP_REFS = -r:$(CPPSHARP_DIR)/CppSharp.dll \
        -r:$(CPPSHARP_DIR)/CppSharp.AST.dll \
+       -r:$(CPPSHARP_DIR)/CppSharp.Parser.dll \
        -r:$(CPPSHARP_DIR)/CppSharp.Parser.CSharp.dll \
        -r:$(CPPSHARP_DIR)/CppSharp.Generator.dll
 
@@ -10,8 +37,8 @@ SRC_ROOT = ../..
 MONO_OPTIONS_SRC = $(SRC_ROOT)/mcs/class/Mono.Options/Mono.Options/Options.cs
 
 .stamp-clone:
-       @if [ ! -d $(CPPSHARP_DIR) ]; then \
-               git clone git://github.com/xamarin/CppSharpBinaries.git $(CPPSHARP_DIR) && touch $@; \
+       @if [ ! -d $(CPPSHARP_BASE_DIR) ]; then \
+               git clone -b 60f763a9 --depth 1 git://github.com/xamarin/CppSharpBinaries.git $(CPPSHARP_DIR) && touch $@; \
        fi
 
 MonoAotOffsetsDumper.exe: .stamp-clone MonoAotOffsetsDumper.cs $(MONO_OPTIONS_SRC)
index e04a23809a5428a760d06b8225467abacd3bbdaf..0f9a984833d766fdc48ceba51617882d361f3237 100644 (file)
@@ -235,7 +235,7 @@ namespace CppSharp
                 if (!driver.ParseCode())
                     return;
 
-                Dump(driver.ASTContext, driver.TargetInfo, target);
+                Dump(driver.Context.ASTContext, driver.Context.TargetInfo, target);
             }
         }
 
@@ -244,13 +244,13 @@ namespace CppSharp
             foreach (var header in driver.Options.Headers)
             {
                 var source = driver.Project.AddFile(header);
-                source.Options = driver.BuildParseOptions(source);
+                source.Options = driver.BuildParserOptions(source);
 
                 if (header.Contains ("mini"))
                     continue;
 
-                source.Options.addDefines ("HAVE_SGEN_GC");
-                source.Options.addDefines ("HAVE_MOVING_COLLECTOR");
+                source.Options.AddDefines ("HAVE_SGEN_GC");
+                source.Options.AddDefines ("HAVE_MOVING_COLLECTOR");
             }
         }
 
@@ -306,22 +306,24 @@ namespace CppSharp
         {
             var options = driver.Options;
             options.DryRun = true;
-            options.Verbose = false;
             options.LibraryName = "Mono";
-            options.MicrosoftMode = false;
-            options.addArguments("-xc");
-            options.addArguments("-std=gnu99");
-            options.addDefines("CPPSHARP");
+
+            var parserOptions = driver.ParserOptions;
+            parserOptions.Verbose = false;
+            parserOptions.MicrosoftMode = false;
+            parserOptions.AddArguments("-xc");
+            parserOptions.AddArguments("-std=gnu99");
+            parserOptions.AddDefines("CPPSHARP");
 
             foreach (var define in target.Defines)
-                options.addDefines(define);
+                parserOptions.AddDefines(define);
 
             SetupToolchainPaths(driver, target);
 
-            SetupMono(options, target);
+            SetupMono(driver, target);
         }
 
-        static void SetupMono(DriverOptions options, Target target)
+        static void SetupMono(Driver driver, Target target)
         {
             string targetPath;
             switch (target.Platform) {
@@ -356,7 +358,7 @@ namespace CppSharp
             };
 
             foreach (var inc in includeDirs)
-                options.addIncludeDirs(inc);
+                driver.ParserOptions.AddIncludeDirs(inc);
 
             var filesToParse = new[]
             {
@@ -365,15 +367,15 @@ namespace CppSharp
             };
 
             foreach (var file in filesToParse)
-                options.Headers.Add(file);
+                driver.Options.Headers.Add(file);
         }
 
         static void SetupMSVC(Driver driver, string triple)
         {
-            var options = driver.Options;
+            var parserOptions = driver.ParserOptions;
 
-            options.Abi = Parser.AST.CppAbi.Microsoft;
-            options.MicrosoftMode = true;
+            parserOptions.Abi = Parser.AST.CppAbi.Microsoft;
+            parserOptions.MicrosoftMode = true;
 
             var systemIncludeDirs = new[]
             {
@@ -382,9 +384,9 @@ namespace CppSharp
             };
 
             foreach (var inc in systemIncludeDirs)
-                options.addSystemIncludeDirs(inc);
+                parserOptions.AddSystemIncludeDirs(inc);
 
-            options.addDefines("HOST_WIN32");
+            parserOptions.AddDefines("HOST_WIN32");
         }
 
         static void SetupToolchainPaths(Driver driver, Target target)
@@ -487,7 +489,7 @@ namespace CppSharp
 
         static void SetupXcode(Driver driver, Target target)
         {
-            var options = driver.Options;
+            var parserOptions = driver.ParserOptions;
 
             var builtinsPath = GetXcodeBuiltinIncludesFolder();
             string includePath;
@@ -503,12 +505,12 @@ namespace CppSharp
                 throw new ArgumentOutOfRangeException ();
             }
 
-            options.addSystemIncludeDirs(builtinsPath);
-            options.addSystemIncludeDirs(includePath);
+            parserOptions.AddSystemIncludeDirs(builtinsPath);
+            parserOptions.AddSystemIncludeDirs(includePath);
 
-            options.NoBuiltinIncludes = true;
-            options.NoStandardIncludes = true;
-            options.TargetTriple = target.Triple;
+            parserOptions.NoBuiltinIncludes = true;
+            parserOptions.NoStandardIncludes = true;
+            parserOptions.TargetTriple = target.Triple;
         }
 
         static string GetAndroidHostToolchainPath()
@@ -555,9 +557,10 @@ namespace CppSharp
         static void SetupAndroidNDK(Driver driver, Target target)
         {
             var options = driver.Options;
+            var parserOptions = driver.ParserOptions;
 
             var builtinsPath = GetAndroidBuiltinIncludesFolder();
-            options.addSystemIncludeDirs(builtinsPath);
+            parserOptions.AddSystemIncludeDirs(builtinsPath);
 
             var androidNdkRoot = GetAndroidNdkPath ();
             const int androidNdkApiLevel = 21;
@@ -565,11 +568,11 @@ namespace CppSharp
             var toolchainPath = Path.Combine(androidNdkRoot, "platforms",
                 "android-" + androidNdkApiLevel, "arch-" + GetArchFromTriple(target.Triple),
                 "usr", "include");
-            options.addSystemIncludeDirs(toolchainPath);
+            parserOptions.AddSystemIncludeDirs(toolchainPath);
 
-            options.NoBuiltinIncludes = true;
-            options.NoStandardIncludes = true;
-            options.TargetTriple = target.Triple;
+            parserOptions.NoBuiltinIncludes = true;
+            parserOptions.NoStandardIncludes = true;
+            parserOptions.TargetTriple = target.Triple;
         }
 
         static uint GetTypeAlign(ParserTargetInfo target, ParserIntType type)
@@ -638,8 +641,8 @@ namespace CppSharp
         {
             var targetFile = target.Triple;
 
-                       if (!string.IsNullOrEmpty (OutputDir))
-                               targetFile = Path.Combine (OutputDir, targetFile);
+            if (!string.IsNullOrEmpty (OutputDir))
+                targetFile = Path.Combine (OutputDir, targetFile);
 
             targetFile += ".h";
 
@@ -754,7 +757,7 @@ namespace CppSharp
             var types = new List<string>
             {
                 "MonoObject",
-               "MonoObjectHandlePayload",
+                "MonoObjectHandlePayload",
                 "MonoClass",
                 "MonoVTable",
                 "MonoDelegate",
@@ -803,7 +806,7 @@ namespace CppSharp
                 "SeqPointInfo",
                 "DynCallArgs", 
                 "MonoLMFTramp",
-            };            
+            };
 
             DumpClasses(writer, ctx, optionalTypes, optional: true);
 
@@ -813,8 +816,8 @@ namespace CppSharp
         static void DumpStruct(TextWriter writer, Class @class)
         {
             var name = @class.Name;
-                       if (name.StartsWith ("_", StringComparison.Ordinal))
-                               name = name.Substring (1);
+            if (name.StartsWith ("_", StringComparison.Ordinal))
+                name = name.Substring (1);
 
             foreach (var field in @class.Fields)
             {
@@ -823,8 +826,10 @@ namespace CppSharp
                 if (name == "SgenThreadInfo" && field.Name == "regs")
                     continue;
 
+                var layout = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr);
+
                 writer.WriteLine("DECL_OFFSET2({0},{1},{2})", name, field.Name,
-                    field.Offset / 8);
+                    layout.Offset);
             }
         }
     }