diff options
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Framework/Servers/BaseOpenSimServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/BaseOpenSimServer.cs | 466 |
1 files changed, 16 insertions, 450 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 5b2d7dc..c0dc907 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Diagnostics; | ||
31 | using System.IO; | 30 | using System.IO; |
32 | using System.Reflection; | 31 | using System.Reflection; |
33 | using System.Text; | 32 | using System.Text; |
@@ -38,6 +37,8 @@ using log4net; | |||
38 | using log4net.Appender; | 37 | using log4net.Appender; |
39 | using log4net.Core; | 38 | using log4net.Core; |
40 | using log4net.Repository; | 39 | using log4net.Repository; |
40 | using OpenMetaverse; | ||
41 | using OpenMetaverse.StructuredData; | ||
41 | using OpenSim.Framework; | 42 | using OpenSim.Framework; |
42 | using OpenSim.Framework.Console; | 43 | using OpenSim.Framework.Console; |
43 | using OpenSim.Framework.Monitoring; | 44 | using OpenSim.Framework.Monitoring; |
@@ -45,16 +46,12 @@ using OpenSim.Framework.Servers; | |||
45 | using OpenSim.Framework.Servers.HttpServer; | 46 | using OpenSim.Framework.Servers.HttpServer; |
46 | using Timer=System.Timers.Timer; | 47 | using Timer=System.Timers.Timer; |
47 | 48 | ||
48 | using OpenMetaverse; | ||
49 | using OpenMetaverse.StructuredData; | ||
50 | |||
51 | |||
52 | namespace OpenSim.Framework.Servers | 49 | namespace OpenSim.Framework.Servers |
53 | { | 50 | { |
54 | /// <summary> | 51 | /// <summary> |
55 | /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) | 52 | /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) |
56 | /// </summary> | 53 | /// </summary> |
57 | public abstract class BaseOpenSimServer | 54 | public abstract class BaseOpenSimServer : ServerBase |
58 | { | 55 | { |
59 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
60 | 57 | ||
@@ -63,27 +60,6 @@ namespace OpenSim.Framework.Servers | |||
63 | /// server. | 60 | /// server. |
64 | /// </summary> | 61 | /// </summary> |
65 | private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); | 62 | private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); |
66 | |||
67 | protected CommandConsole m_console; | ||
68 | protected OpenSimAppender m_consoleAppender; | ||
69 | protected IAppender m_logFileAppender = null; | ||
70 | |||
71 | /// <summary> | ||
72 | /// Time at which this server was started | ||
73 | /// </summary> | ||
74 | protected DateTime m_startuptime; | ||
75 | |||
76 | /// <summary> | ||
77 | /// Record the initial startup directory for info purposes | ||
78 | /// </summary> | ||
79 | protected string m_startupDirectory = Environment.CurrentDirectory; | ||
80 | |||
81 | /// <summary> | ||
82 | /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. | ||
83 | /// </summary> | ||
84 | protected string m_version; | ||
85 | |||
86 | protected string m_pidFile = String.Empty; | ||
87 | 63 | ||
88 | /// <summary> | 64 | /// <summary> |
89 | /// Random uuid for private data | 65 | /// Random uuid for private data |
@@ -96,30 +72,13 @@ namespace OpenSim.Framework.Servers | |||
96 | get { return m_httpServer; } | 72 | get { return m_httpServer; } |
97 | } | 73 | } |
98 | 74 | ||
99 | public BaseOpenSimServer() | 75 | public BaseOpenSimServer() : base() |
100 | { | 76 | { |
101 | m_startuptime = DateTime.Now; | ||
102 | m_version = VersionInfo.Version; | ||
103 | |||
104 | // Random uuid for private data | 77 | // Random uuid for private data |
105 | m_osSecret = UUID.Random().ToString(); | 78 | m_osSecret = UUID.Random().ToString(); |
106 | 79 | ||
107 | m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); | 80 | m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); |
108 | m_periodicDiagnosticsTimer.Enabled = true; | 81 | m_periodicDiagnosticsTimer.Enabled = true; |
109 | |||
110 | // This thread will go on to become the console listening thread | ||
111 | Thread.CurrentThread.Name = "ConsoleThread"; | ||
112 | |||
113 | ILoggerRepository repository = LogManager.GetRepository(); | ||
114 | IAppender[] appenders = repository.GetAppenders(); | ||
115 | |||
116 | foreach (IAppender appender in appenders) | ||
117 | { | ||
118 | if (appender.Name == "LogFileAppender") | ||
119 | { | ||
120 | m_logFileAppender = appender; | ||
121 | } | ||
122 | } | ||
123 | } | 82 | } |
124 | 83 | ||
125 | /// <summary> | 84 | /// <summary> |
@@ -127,83 +86,18 @@ namespace OpenSim.Framework.Servers | |||
127 | /// </summary> | 86 | /// </summary> |
128 | protected virtual void StartupSpecific() | 87 | protected virtual void StartupSpecific() |
129 | { | 88 | { |
130 | if (m_console != null) | 89 | if (m_console == null) |
131 | { | 90 | return; |
132 | ILoggerRepository repository = LogManager.GetRepository(); | ||
133 | IAppender[] appenders = repository.GetAppenders(); | ||
134 | |||
135 | foreach (IAppender appender in appenders) | ||
136 | { | ||
137 | if (appender.Name == "Console") | ||
138 | { | ||
139 | m_consoleAppender = (OpenSimAppender)appender; | ||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (null == m_consoleAppender) | ||
145 | { | ||
146 | Notice("No appender named Console found (see the log4net config file for this executable)!"); | ||
147 | } | ||
148 | else | ||
149 | { | ||
150 | m_consoleAppender.Console = m_console; | ||
151 | |||
152 | // If there is no threshold set then the threshold is effectively everything. | ||
153 | if (null == m_consoleAppender.Threshold) | ||
154 | m_consoleAppender.Threshold = Level.All; | ||
155 | |||
156 | Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); | ||
157 | } | ||
158 | |||
159 | m_console.Commands.AddCommand("General", false, "quit", | ||
160 | "quit", | ||
161 | "Quit the application", HandleQuit); | ||
162 | |||
163 | m_console.Commands.AddCommand("General", false, "shutdown", | ||
164 | "shutdown", | ||
165 | "Quit the application", HandleQuit); | ||
166 | |||
167 | m_console.Commands.AddCommand("General", false, "set log level", | ||
168 | "set log level <level>", | ||
169 | "Set the console logging level", HandleLogLevel); | ||
170 | |||
171 | m_console.Commands.AddCommand("General", false, "show info", | ||
172 | "show info", | ||
173 | "Show general information about the server", HandleShow); | ||
174 | |||
175 | m_console.Commands.AddCommand("General", false, "show threads", | ||
176 | "show threads", | ||
177 | "Show thread status", HandleShow); | ||
178 | |||
179 | m_console.Commands.AddCommand("General", false, "show uptime", | ||
180 | "show uptime", | ||
181 | "Show server uptime", HandleShow); | ||
182 | |||
183 | m_console.Commands.AddCommand("General", false, "show version", | ||
184 | "show version", | ||
185 | "Show server version", HandleShow); | ||
186 | |||
187 | m_console.Commands.AddCommand("General", false, "threads abort", | ||
188 | "threads abort <thread-id>", | ||
189 | "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); | ||
190 | |||
191 | m_console.Commands.AddCommand("General", false, "threads show", | ||
192 | "threads show", | ||
193 | "Show thread status. Synonym for \"show threads\"", | ||
194 | (string module, string[] args) => Notice(GetThreadsReport())); | ||
195 | 91 | ||
196 | m_console.Commands.AddCommand("General", false, "force gc", | 92 | RegisterCommonCommands(); |
197 | "force gc", | 93 | |
198 | "Manually invoke runtime garbage collection. For debugging purposes", | 94 | m_console.Commands.AddCommand("General", false, "quit", |
199 | HandleForceGc); | 95 | "quit", |
200 | } | 96 | "Quit the application", HandleQuit); |
201 | } | ||
202 | 97 | ||
203 | private void HandleForceGc(string module, string[] args) | 98 | m_console.Commands.AddCommand("General", false, "shutdown", |
204 | { | 99 | "shutdown", |
205 | MainConsole.Instance.Output("Manually invoking runtime garbage collection"); | 100 | "Quit the application", HandleQuit); |
206 | GC.Collect(); | ||
207 | } | 101 | } |
208 | 102 | ||
209 | /// <summary> | 103 | /// <summary> |
@@ -236,74 +130,11 @@ namespace OpenSim.Framework.Servers | |||
236 | } | 130 | } |
237 | 131 | ||
238 | /// <summary> | 132 | /// <summary> |
239 | /// Get a report about the registered threads in this server. | ||
240 | /// </summary> | ||
241 | protected string GetThreadsReport() | ||
242 | { | ||
243 | // This should be a constant field. | ||
244 | string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; | ||
245 | |||
246 | StringBuilder sb = new StringBuilder(); | ||
247 | Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo(); | ||
248 | |||
249 | sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); | ||
250 | |||
251 | int timeNow = Environment.TickCount & Int32.MaxValue; | ||
252 | |||
253 | sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE"); | ||
254 | sb.Append(Environment.NewLine); | ||
255 | |||
256 | foreach (Watchdog.ThreadWatchdogInfo twi in threads) | ||
257 | { | ||
258 | Thread t = twi.Thread; | ||
259 | |||
260 | sb.AppendFormat( | ||
261 | reportFormat, | ||
262 | t.ManagedThreadId, | ||
263 | t.Name, | ||
264 | timeNow - twi.LastTick, | ||
265 | timeNow - twi.FirstTick, | ||
266 | t.Priority, | ||
267 | t.ThreadState); | ||
268 | |||
269 | sb.Append("\n"); | ||
270 | } | ||
271 | |||
272 | sb.Append("\n"); | ||
273 | |||
274 | // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting | ||
275 | // zero active threads. | ||
276 | int totalThreads = Process.GetCurrentProcess().Threads.Count; | ||
277 | if (totalThreads > 0) | ||
278 | sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); | ||
279 | |||
280 | sb.Append("Main threadpool (excluding script engine pools)\n"); | ||
281 | sb.Append(Util.GetThreadPoolReport()); | ||
282 | |||
283 | return sb.ToString(); | ||
284 | } | ||
285 | |||
286 | /// <summary> | ||
287 | /// Return a report about the uptime of this server | ||
288 | /// </summary> | ||
289 | /// <returns></returns> | ||
290 | protected string GetUptimeReport() | ||
291 | { | ||
292 | StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now)); | ||
293 | sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime)); | ||
294 | sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime)); | ||
295 | |||
296 | return sb.ToString(); | ||
297 | } | ||
298 | |||
299 | /// <summary> | ||
300 | /// Performs initialisation of the scene, such as loading configuration from disk. | 133 | /// Performs initialisation of the scene, such as loading configuration from disk. |
301 | /// </summary> | 134 | /// </summary> |
302 | public virtual void Startup() | 135 | public virtual void Startup() |
303 | { | 136 | { |
304 | m_log.Info("[STARTUP]: Beginning startup processing"); | 137 | m_log.Info("[STARTUP]: Beginning startup processing"); |
305 | |||
306 | EnhanceVersionInformation(); | ||
307 | 138 | ||
308 | m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine); | 139 | m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine); |
309 | // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and | 140 | // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and |
@@ -338,257 +169,7 @@ namespace OpenSim.Framework.Servers | |||
338 | private void HandleQuit(string module, string[] args) | 169 | private void HandleQuit(string module, string[] args) |
339 | { | 170 | { |
340 | Shutdown(); | 171 | Shutdown(); |
341 | } | 172 | } |
342 | |||
343 | private void HandleLogLevel(string module, string[] cmd) | ||
344 | { | ||
345 | if (null == m_consoleAppender) | ||
346 | { | ||
347 | Notice("No appender named Console found (see the log4net config file for this executable)!"); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | if (cmd.Length > 3) | ||
352 | { | ||
353 | string rawLevel = cmd[3]; | ||
354 | |||
355 | ILoggerRepository repository = LogManager.GetRepository(); | ||
356 | Level consoleLevel = repository.LevelMap[rawLevel]; | ||
357 | |||
358 | if (consoleLevel != null) | ||
359 | m_consoleAppender.Threshold = consoleLevel; | ||
360 | else | ||
361 | Notice( | ||
362 | String.Format( | ||
363 | "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF", | ||
364 | rawLevel)); | ||
365 | } | ||
366 | |||
367 | Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); | ||
368 | } | ||
369 | |||
370 | /// <summary> | ||
371 | /// Show help information | ||
372 | /// </summary> | ||
373 | /// <param name="helpArgs"></param> | ||
374 | protected virtual void ShowHelp(string[] helpArgs) | ||
375 | { | ||
376 | Notice(""); | ||
377 | |||
378 | if (helpArgs.Length == 0) | ||
379 | { | ||
380 | Notice("set log level [level] - change the console logging level only. For example, off or debug."); | ||
381 | Notice("show info - show server information (e.g. startup path)."); | ||
382 | Notice("show threads - list tracked threads"); | ||
383 | Notice("show uptime - show server startup time and uptime."); | ||
384 | Notice("show version - show server version."); | ||
385 | Notice(""); | ||
386 | |||
387 | return; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | public virtual void HandleShow(string module, string[] cmd) | ||
392 | { | ||
393 | List<string> args = new List<string>(cmd); | ||
394 | |||
395 | args.RemoveAt(0); | ||
396 | |||
397 | string[] showParams = args.ToArray(); | ||
398 | |||
399 | switch (showParams[0]) | ||
400 | { | ||
401 | case "info": | ||
402 | ShowInfo(); | ||
403 | break; | ||
404 | |||
405 | case "threads": | ||
406 | Notice(GetThreadsReport()); | ||
407 | break; | ||
408 | |||
409 | case "uptime": | ||
410 | Notice(GetUptimeReport()); | ||
411 | break; | ||
412 | |||
413 | case "version": | ||
414 | Notice(GetVersionText()); | ||
415 | break; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | public virtual void HandleThreadsAbort(string module, string[] cmd) | ||
420 | { | ||
421 | if (cmd.Length != 3) | ||
422 | { | ||
423 | MainConsole.Instance.Output("Usage: threads abort <thread-id>"); | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | int threadId; | ||
428 | if (!int.TryParse(cmd[2], out threadId)) | ||
429 | { | ||
430 | MainConsole.Instance.Output("ERROR: Thread id must be an integer"); | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | if (Watchdog.AbortThread(threadId)) | ||
435 | MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); | ||
436 | else | ||
437 | MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); | ||
438 | } | ||
439 | |||
440 | protected void ShowInfo() | ||
441 | { | ||
442 | Notice(GetVersionText()); | ||
443 | Notice("Startup directory: " + m_startupDirectory); | ||
444 | if (null != m_consoleAppender) | ||
445 | Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold)); | ||
446 | } | ||
447 | |||
448 | protected string GetVersionText() | ||
449 | { | ||
450 | return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion); | ||
451 | } | ||
452 | |||
453 | /// <summary> | ||
454 | /// Console output is only possible if a console has been established. | ||
455 | /// That is something that cannot be determined within this class. So | ||
456 | /// all attempts to use the console MUST be verified. | ||
457 | /// </summary> | ||
458 | /// <param name="msg"></param> | ||
459 | protected void Notice(string msg) | ||
460 | { | ||
461 | if (m_console != null) | ||
462 | { | ||
463 | m_console.Output(msg); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /// <summary> | ||
468 | /// Console output is only possible if a console has been established. | ||
469 | /// That is something that cannot be determined within this class. So | ||
470 | /// all attempts to use the console MUST be verified. | ||
471 | /// </summary> | ||
472 | /// <param name="format"></param> | ||
473 | /// <param name="components"></param> | ||
474 | protected void Notice(string format, params string[] components) | ||
475 | { | ||
476 | if (m_console != null) | ||
477 | m_console.OutputFormat(format, components); | ||
478 | } | ||
479 | |||
480 | /// <summary> | ||
481 | /// Enhance the version string with extra information if it's available. | ||
482 | /// </summary> | ||
483 | protected void EnhanceVersionInformation() | ||
484 | { | ||
485 | string buildVersion = string.Empty; | ||
486 | |||
487 | // The subversion information is deprecated and will be removed at a later date | ||
488 | // Add subversion revision information if available | ||
489 | // Try file "svn_revision" in the current directory first, then the .svn info. | ||
490 | // This allows to make the revision available in simulators not running from the source tree. | ||
491 | // FIXME: Making an assumption about the directory we're currently in - we do this all over the place | ||
492 | // elsewhere as well | ||
493 | string gitDir = "../.git/"; | ||
494 | string gitRefPointerPath = gitDir + "HEAD"; | ||
495 | |||
496 | string svnRevisionFileName = "svn_revision"; | ||
497 | string svnFileName = ".svn/entries"; | ||
498 | string manualVersionFileName = ".version"; | ||
499 | string inputLine; | ||
500 | int strcmp; | ||
501 | |||
502 | if (File.Exists(manualVersionFileName)) | ||
503 | { | ||
504 | using (StreamReader CommitFile = File.OpenText(manualVersionFileName)) | ||
505 | buildVersion = CommitFile.ReadLine(); | ||
506 | |||
507 | m_version += buildVersion ?? ""; | ||
508 | } | ||
509 | else if (File.Exists(gitRefPointerPath)) | ||
510 | { | ||
511 | // m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath); | ||
512 | |||
513 | string rawPointer = ""; | ||
514 | |||
515 | using (StreamReader pointerFile = File.OpenText(gitRefPointerPath)) | ||
516 | rawPointer = pointerFile.ReadLine(); | ||
517 | |||
518 | // m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer); | ||
519 | |||
520 | Match m = Regex.Match(rawPointer, "^ref: (.+)$"); | ||
521 | |||
522 | if (m.Success) | ||
523 | { | ||
524 | // m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value); | ||
525 | |||
526 | string gitRef = m.Groups[1].Value; | ||
527 | string gitRefPath = gitDir + gitRef; | ||
528 | if (File.Exists(gitRefPath)) | ||
529 | { | ||
530 | // m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath); | ||
531 | |||
532 | using (StreamReader refFile = File.OpenText(gitRefPath)) | ||
533 | { | ||
534 | string gitHash = refFile.ReadLine(); | ||
535 | m_version += gitHash.Substring(0, 7); | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | // Remove the else logic when subversion mirror is no longer used | ||
543 | if (File.Exists(svnRevisionFileName)) | ||
544 | { | ||
545 | StreamReader RevisionFile = File.OpenText(svnRevisionFileName); | ||
546 | buildVersion = RevisionFile.ReadLine(); | ||
547 | buildVersion.Trim(); | ||
548 | RevisionFile.Close(); | ||
549 | } | ||
550 | |||
551 | if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName)) | ||
552 | { | ||
553 | StreamReader EntriesFile = File.OpenText(svnFileName); | ||
554 | inputLine = EntriesFile.ReadLine(); | ||
555 | while (inputLine != null) | ||
556 | { | ||
557 | // using the dir svn revision at the top of entries file | ||
558 | strcmp = String.Compare(inputLine, "dir"); | ||
559 | if (strcmp == 0) | ||
560 | { | ||
561 | buildVersion = EntriesFile.ReadLine(); | ||
562 | break; | ||
563 | } | ||
564 | else | ||
565 | { | ||
566 | inputLine = EntriesFile.ReadLine(); | ||
567 | } | ||
568 | } | ||
569 | EntriesFile.Close(); | ||
570 | } | ||
571 | |||
572 | m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | protected void CreatePIDFile(string path) | ||
577 | { | ||
578 | try | ||
579 | { | ||
580 | string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); | ||
581 | FileStream fs = File.Create(path); | ||
582 | |||
583 | Byte[] buf = Encoding.ASCII.GetBytes(pidstring); | ||
584 | fs.Write(buf, 0, buf.Length); | ||
585 | fs.Close(); | ||
586 | m_pidFile = path; | ||
587 | } | ||
588 | catch (Exception) | ||
589 | { | ||
590 | } | ||
591 | } | ||
592 | 173 | ||
593 | public string osSecret { | 174 | public string osSecret { |
594 | // Secret uuid for the simulator | 175 | // Secret uuid for the simulator |
@@ -607,20 +188,5 @@ namespace OpenSim.Framework.Servers | |||
607 | return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); | 188 | return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); |
608 | } | 189 | } |
609 | } | 190 | } |
610 | |||
611 | protected void RemovePIDFile() | ||
612 | { | ||
613 | if (m_pidFile != String.Empty) | ||
614 | { | ||
615 | try | ||
616 | { | ||
617 | File.Delete(m_pidFile); | ||
618 | m_pidFile = String.Empty; | ||
619 | } | ||
620 | catch (Exception) | ||
621 | { | ||
622 | } | ||
623 | } | ||
624 | } | ||
625 | } | 191 | } |
626 | } | 192 | } \ No newline at end of file |