[Profiler] Use the correct function to increment the refcount
[mono.git] / mcs / class / Microsoft.Build / Microsoft.Build.Execution / BuildManager.cs
1 // BuildManager.cs
2 //
3 // Author:
4 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
5 //   Atsushi Enomoto (atsushi@xamarin.com)
6 //
7 // Copyright (C) 2011,2013 Xamarin Inc.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using Microsoft.Build.Evaluation;
30 using System;
31 using System.Collections.Generic;
32 using System.Threading;
33 using Microsoft.Build.Internal;
34 using System.Linq;
35
36 namespace Microsoft.Build.Execution
37 {
38         public class BuildManager
39         {
40                 static BuildManager default_manager = new BuildManager ();
41
42                 public static BuildManager DefaultBuildManager {
43                         get { return default_manager; }
44                 }
45                 
46                 public BuildManager ()
47                 {
48                 }
49
50                 public BuildManager (string hostName)
51                 {
52                         throw new NotImplementedException ();
53                 }
54                 
55                 public void Dispose ()
56                 {
57                         WaitHandle.WaitAll (submissions.Select (s => s.WaitHandle).ToArray ());
58                         BuildNodeManager.Stop ();
59                 }
60
61                 ~BuildManager ()
62                 {
63                         // maybe processes created by out-of-process nodes should be signaled.
64                 }
65
66                 readonly List<BuildSubmission> submissions = new List<BuildSubmission> ();
67                 
68                 BuildParameters ongoing_build_parameters;
69                 
70                 internal BuildParameters OngoingBuildParameters {
71                         get { return ongoing_build_parameters; }
72                 }
73
74                 public void BeginBuild (BuildParameters parameters)
75                 {
76                         if (ongoing_build_parameters != null)
77                                 throw new InvalidOperationException ("There is already ongoing build");
78                         ongoing_build_parameters = parameters.Clone ();
79                 }
80
81                 public BuildResult Build (BuildParameters parameters, BuildRequestData requestData)
82                 {
83                         BeginBuild (parameters);
84                         var ret = BuildRequest (requestData);
85                         EndBuild ();
86                         return ret;
87                 }
88
89                 public BuildResult BuildRequest (BuildRequestData requestData)
90                 {
91                         var sub = PendBuildRequest (requestData);
92                         sub.Execute ();
93                         return sub.BuildResult;
94                 }
95                 
96                 public void CancelAllSubmissions ()
97                 {
98                         foreach (var sub in submissions) {
99                                 try {
100                                         if (!sub.IsCompleted)
101                                                 sub.Cancel ();
102                                 } catch (InvalidOperationException) {
103                                         // some submissions could be already done during this iteration. Ignore that.
104                                 }
105                         }
106                         submissions.Clear ();
107                 }
108
109                 public void EndBuild ()
110                 {
111                         if (ongoing_build_parameters == null)
112                                 throw new InvalidOperationException ("Build has not started");
113                         if (submissions.Count > 0)
114                                 WaitHandle.WaitAll (submissions.Select (s => s.WaitHandle).ToArray ());
115                         ongoing_build_parameters = null;
116                 }
117                 
118                 Dictionary<Project,ProjectInstance> instances = new Dictionary<Project, ProjectInstance> ();
119
120                 public ProjectInstance GetProjectInstanceForBuild (Project project)
121                 {
122                         if (project == null)
123                                 throw new ArgumentNullException ("project");
124                         if (project.FullPath == null)
125                                 throw new ArgumentNullException ("project", "FullPath parameter in the project cannot be null.");
126                         if (project.FullPath == string.Empty)
127                                 throw new ArgumentException ("FullPath parameter in the project cannot be empty.", "project");
128                         // other than that, any invalid path character is accepted...
129                         
130                         return GetProjectInstanceForBuildInternal (project);
131                 }
132                         
133                 internal ProjectInstance GetProjectInstanceForBuildInternal (Project project)
134                 {
135                         if (!instances.ContainsKey (project))
136                                 instances [project] = project.CreateProjectInstance ();
137                         return instances [project];
138                 }
139
140                 public BuildSubmission PendBuildRequest (BuildRequestData requestData)
141                 {
142                         if (ongoing_build_parameters == null)
143                                 throw new InvalidOperationException ("This method cannot be called before calling BeginBuild method.");
144                         var sub = new BuildSubmission (this, requestData);
145                         submissions.Add (sub);
146                         return sub;
147                 }
148
149                 public void ResetCaches ()
150                 {
151                         if (OngoingBuildParameters != null)
152                                 throw new InvalidOperationException ("Cannot reset caches while builds are in progress.");
153                         
154                         BuildNodeManager.ResetCaches ();
155                 }
156                 
157                 BuildNodeManager build_node_manager;
158                 
159                 internal BuildNodeManager BuildNodeManager {
160                         get {
161                                 if (build_node_manager == null)
162                                                 build_node_manager = new BuildNodeManager (this);
163                                 return build_node_manager;
164                         }
165                 }
166         }
167 }