aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-11-25 23:56:32 +0000
committerJustin Clark-Casey (justincc)2014-11-25 23:56:32 +0000
commit86367d7219b3bd52f63045b2b17bcbde328844ed (patch)
tree789227d95cb152a437481e741b55d86dfeba9f74
parentFix ghosts copy of SimulatorFeatureModule to enable logging. (diff)
downloadopensim-SC_OLD-86367d7219b3bd52f63045b2b17bcbde328844ed.zip
opensim-SC_OLD-86367d7219b3bd52f63045b2b17bcbde328844ed.tar.gz
opensim-SC_OLD-86367d7219b3bd52f63045b2b17bcbde328844ed.tar.bz2
opensim-SC_OLD-86367d7219b3bd52f63045b2b17bcbde328844ed.tar.xz
refactor: Move methods to start a monitored thread, start work in its own thread and run work in the jobengine from Watchdog to a WorkManager class.
This is to achieve a clean separation of concerns - the watchdog is an inappropriate place for work management. Also adds a WorkManager.RunInThreadPool() class which feeds through to Util.FireAndForget. Also switches around the name and obj arguments to the new RunInThread() and RunJob() methods so that the callback obj comes after the callback as seen in the SDK and elsewhere
-rw-r--r--OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs4
-rw-r--r--OpenSim/Framework/Monitoring/JobEngine.cs2
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs149
-rw-r--r--OpenSim/Framework/Monitoring/WorkManager.cs212
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs4
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs22
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs2
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs2
27 files changed, 270 insertions, 185 deletions
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
index 9fbc1b3..7d57de1 100644
--- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
@@ -561,7 +561,7 @@ namespace OpenSim.Groups
561 561
562 // so we have the list of urls to send the notice to 562 // so we have the list of urls to send the notice to
563 // this may take a long time... 563 // this may take a long time...
564 Watchdog.RunInThread(delegate 564 WorkManager.RunInThread(delegate
565 { 565 {
566 foreach (string u in urls) 566 foreach (string u in urls)
567 { 567 {
@@ -572,7 +572,7 @@ namespace OpenSim.Groups
572 hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID)); 572 hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
573 } 573 }
574 } 574 }
575 }, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID) , null); 575 }, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
576 576
577 return true; 577 return true;
578 } 578 }
diff --git a/OpenSim/Framework/Monitoring/JobEngine.cs b/OpenSim/Framework/Monitoring/JobEngine.cs
index 4a46328..5925867 100644
--- a/OpenSim/Framework/Monitoring/JobEngine.cs
+++ b/OpenSim/Framework/Monitoring/JobEngine.cs
@@ -125,7 +125,7 @@ namespace OpenSim.Framework.Monitoring
125 125
126 StatsManager.RegisterStat(m_requestsWaitingStat); 126 StatsManager.RegisterStat(m_requestsWaitingStat);
127 127
128 Watchdog.StartThread( 128 WorkManager.StartThread(
129 ProcessRequests, 129 ProcessRequests,
130 "JobEngineThread", 130 "JobEngineThread",
131 ThreadPriority.Normal, 131 ThreadPriority.Normal,
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index 0feec7c..a644fa5 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -38,6 +38,8 @@ namespace OpenSim.Framework.Monitoring
38 /// </summary> 38 /// </summary>
39 public static class Watchdog 39 public static class Watchdog
40 { 40 {
41 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
42
41 /// <summary>Timer interval in milliseconds for the watchdog timer</summary> 43 /// <summary>Timer interval in milliseconds for the watchdog timer</summary>
42 public const double WATCHDOG_INTERVAL_MS = 2500.0d; 44 public const double WATCHDOG_INTERVAL_MS = 2500.0d;
43 45
@@ -133,8 +135,6 @@ namespace OpenSim.Framework.Monitoring
133 /// /summary> 135 /// /summary>
134 public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout; 136 public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
135 137
136 public static JobEngine JobEngine { get; private set; }
137
138 /// <summary> 138 /// <summary>
139 /// Is this watchdog active? 139 /// Is this watchdog active?
140 /// </summary> 140 /// </summary>
@@ -143,7 +143,7 @@ namespace OpenSim.Framework.Monitoring
143 get { return m_enabled; } 143 get { return m_enabled; }
144 set 144 set
145 { 145 {
146// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value); 146 // m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
147 147
148 if (value == m_enabled) 148 if (value == m_enabled)
149 return; 149 return;
@@ -159,9 +159,8 @@ namespace OpenSim.Framework.Monitoring
159 m_watchdogTimer.Enabled = m_enabled; 159 m_watchdogTimer.Enabled = m_enabled;
160 } 160 }
161 } 161 }
162 private static bool m_enabled;
163 162
164 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 163 private static bool m_enabled;
165 private static Dictionary<int, ThreadWatchdogInfo> m_threads; 164 private static Dictionary<int, ThreadWatchdogInfo> m_threads;
166 private static System.Timers.Timer m_watchdogTimer; 165 private static System.Timers.Timer m_watchdogTimer;
167 166
@@ -175,7 +174,6 @@ namespace OpenSim.Framework.Monitoring
175 174
176 static Watchdog() 175 static Watchdog()
177 { 176 {
178 JobEngine = new JobEngine();
179 m_threads = new Dictionary<int, ThreadWatchdogInfo>(); 177 m_threads = new Dictionary<int, ThreadWatchdogInfo>();
180 m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); 178 m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
181 m_watchdogTimer.AutoReset = false; 179 m_watchdogTimer.AutoReset = false;
@@ -183,94 +181,19 @@ namespace OpenSim.Framework.Monitoring
183 } 181 }
184 182
185 /// <summary> 183 /// <summary>
186 /// Start a new thread that is tracked by the watchdog timer. 184 /// Add a thread to the watchdog tracker.
187 /// </summary>
188 /// <param name="start">The method that will be executed in a new thread</param>
189 /// <param name="name">A name to give to the new thread</param>
190 /// <param name="priority">Priority to run the thread at</param>
191 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
192 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
193 /// <param name="log">If true then creation of thread is logged.</param>
194 /// <returns>The newly created Thread object</returns>
195 public static Thread StartThread(
196 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
197 {
198 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log);
199 }
200
201 /// <summary>
202 /// Start a new thread that is tracked by the watchdog
203 /// </summary> 185 /// </summary>
204 /// <param name="start">The method that will be executed in a new thread</param> 186 /// <param name="info">Information about the thread.</info>
205 /// <param name="name">A name to give to the new thread</param> 187 /// <param name="info">Name of the thread.</info>
206 /// <param name="priority">Priority to run the thread at</param>
207 /// <param name="isBackground">True to run this thread as a background
208 /// thread, otherwise false</param>
209 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
210 /// <param name="alarmMethod">
211 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
212 /// Normally, this will just return some useful debugging information.
213 /// </param>
214 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
215 /// <param name="log">If true then creation of thread is logged.</param> 188 /// <param name="log">If true then creation of thread is logged.</param>
216 /// <returns>The newly created Thread object</returns> 189 public static void AddThread(ThreadWatchdogInfo info, string name, bool log = true)
217 public static Thread StartThread(
218 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
219 bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
220 { 190 {
221 Thread thread = new Thread(start);
222 thread.Priority = priority;
223 thread.IsBackground = isBackground;
224
225 ThreadWatchdogInfo twi
226 = new ThreadWatchdogInfo(thread, timeout, name)
227 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
228
229 if (log) 191 if (log)
230 m_log.DebugFormat( 192 m_log.DebugFormat(
231 "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, twi.Thread.ManagedThreadId); 193 "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, info.Thread.ManagedThreadId);
232 194
233 lock (m_threads) 195 lock (m_threads)
234 m_threads.Add(twi.Thread.ManagedThreadId, twi); 196 m_threads.Add(info.Thread.ManagedThreadId, info);
235
236 thread.Start();
237 thread.Name = name;
238
239
240 return thread;
241 }
242
243 /// <summary>
244 /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
245 /// not propogate it.
246 /// </summary>
247 /// <param name="callback">Code for the thread to execute.</param>
248 /// <param name="name">Name of the thread</param>
249 /// <param name="obj">Object to pass to the thread.</param>
250 public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false)
251 {
252 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
253 {
254 Culture.SetCurrentCulture();
255 callback(obj);
256 return;
257 }
258
259 ThreadStart ts = new ThreadStart(delegate()
260 {
261 try
262 {
263 Culture.SetCurrentCulture();
264 callback(obj);
265 Watchdog.RemoveThread(log:false);
266 }
267 catch (Exception e)
268 {
269 m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
270 }
271 });
272
273 StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
274 } 197 }
275 198
276 /// <summary> 199 /// <summary>
@@ -361,7 +284,7 @@ namespace OpenSim.Framework.Monitoring
361 } 284 }
362 catch { } 285 catch { }
363 } 286 }
364 287
365 /// <summary> 288 /// <summary>
366 /// Get currently watched threads for diagnostic purposes 289 /// Get currently watched threads for diagnostic purposes
367 /// </summary> 290 /// </summary>
@@ -453,55 +376,5 @@ namespace OpenSim.Framework.Monitoring
453 376
454 m_watchdogTimer.Start(); 377 m_watchdogTimer.Start();
455 } 378 }
456
457 /// <summary>
458 /// Run a job.
459 /// </summary>
460 /// <remarks>
461 /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job
462 /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is
463 /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to
464 /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small
465 /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more
466 /// sophisticated implementation could perform jobs concurrently when the server is under low load.
467 ///
468 /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any
469 /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine
470 /// beyond a single thread will require considerable thought.
471 ///
472 /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot
473 /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues
474 /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where
475 /// the job engine could be improved and so CPU utilization improved by better management of concurrency within
476 /// OpenSimulator.
477 /// </remarks>
478 /// <param name="jobType">General classification for the job (e.g. "RezAttachments").</param>
479 /// <param name="callback">Callback for job.</param>
480 /// <param name="name">Specific name of job (e.g. "RezAttachments for Joe Bloggs"</param>
481 /// <param name="obj">Object to pass to callback when run</param>
482 /// <param name="canRunInThisThread">If set to true then the job may be run in ths calling thread.</param>
483 /// <param name="mustNotTimeout">If the true then the job must never timeout.</param>
484 /// <param name="log">If set to true then extra logging is performed.</param>
485 public static void RunJob(
486 string jobType, WaitCallback callback, string name, object obj,
487 bool canRunInThisThread = false, bool mustNotTimeout = false,
488 bool log = false)
489 {
490 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
491 {
492 Culture.SetCurrentCulture();
493 callback(obj);
494 return;
495 }
496
497 if (JobEngine.IsRunning)
498 JobEngine.QueueRequest(name, callback, obj);
499 else if (canRunInThisThread)
500 callback(obj);
501 else if (mustNotTimeout)
502 RunInThread(callback, name, obj, log);
503 else
504 Util.FireAndForget(callback, obj, name);
505 }
506 } 379 }
507} \ No newline at end of file 380} \ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs
new file mode 100644
index 0000000..9d0eefc
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/WorkManager.cs
@@ -0,0 +1,212 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Threading;
31using log4net;
32
33namespace OpenSim.Framework.Monitoring
34{
35 /// <summary>
36 /// Manages various work items in the simulator.
37 /// </summary>
38 /// <remarks>
39 /// Currently, here work can be started
40 /// * As a long-running and monitored thread.
41 /// * In a thread that will never timeout but where the job is expected to eventually complete.
42 /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins).
43 /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps,
44 /// network waits, etc.).
45 ///
46 /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse
47 /// range of sources (client actions, incoming network, outgoing network calls, etc.).
48 ///
49 /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to
50 /// WorkManager.RunInThreadPool().
51 /// </remarks>
52 public static class WorkManager
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
55
56 public static JobEngine JobEngine { get; private set; }
57
58 static WorkManager()
59 {
60 JobEngine = new JobEngine();
61 }
62
63 /// <summary>
64 /// Start a new long-lived thread.
65 /// </summary>
66 /// <param name="start">The method that will be executed in a new thread</param>
67 /// <param name="name">A name to give to the new thread</param>
68 /// <param name="priority">Priority to run the thread at</param>
69 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
70 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
71 /// <param name="log">If true then creation of thread is logged.</param>
72 /// <returns>The newly created Thread object</returns>
73 public static Thread StartThread(
74 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
75 {
76 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS, log);
77 }
78
79 /// <summary>
80 /// Start a new thread that is tracked by the watchdog
81 /// </summary>
82 /// <param name="start">The method that will be executed in a new thread</param>
83 /// <param name="name">A name to give to the new thread</param>
84 /// <param name="priority">Priority to run the thread at</param>
85 /// <param name="isBackground">True to run this thread as a background
86 /// thread, otherwise false</param>
87 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
88 /// <param name="alarmMethod">
89 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
90 /// Normally, this will just return some useful debugging information.
91 /// </param>
92 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
93 /// <param name="log">If true then creation of thread is logged.</param>
94 /// <returns>The newly created Thread object</returns>
95 public static Thread StartThread(
96 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
97 bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
98 {
99 Thread thread = new Thread(start);
100 thread.Priority = priority;
101 thread.IsBackground = isBackground;
102
103 Watchdog.ThreadWatchdogInfo twi
104 = new Watchdog.ThreadWatchdogInfo(thread, timeout, name)
105 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
106
107 Watchdog.AddThread(twi, name, log:log);
108
109 thread.Start();
110 thread.Name = name;
111
112 return thread;
113 }
114
115 /// <summary>
116 /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
117 /// not propogate it.
118 /// </summary>
119 /// <param name="callback">Code for the thread to execute.</param>
120 /// <param name="obj">Object to pass to the thread.</param>
121 /// <param name="name">Name of the thread</param>
122 public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false)
123 {
124 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
125 {
126 Culture.SetCurrentCulture();
127 callback(obj);
128 return;
129 }
130
131 ThreadStart ts = new ThreadStart(delegate()
132 {
133 try
134 {
135 Culture.SetCurrentCulture();
136 callback(obj);
137 Watchdog.RemoveThread(log:false);
138 }
139 catch (Exception e)
140 {
141 m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
142 }
143 });
144
145 StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
146 }
147
148 /// <summary>
149 /// Run the callback via a threadpool thread.
150 /// </summary>
151 /// <remarks>
152 /// Such jobs may run after some delay but must always complete.
153 /// </remarks>
154 /// <param name="callback"></param>
155 /// <param name="obj"></param>
156 /// <param name="name">The name of the job. This is used in monitoring and debugging.</param>
157 public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name)
158 {
159 Util.FireAndForget(callback, obj, name);
160 }
161
162 /// <summary>
163 /// Run a job.
164 /// </summary>
165 /// <remarks>
166 /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job
167 /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is
168 /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to
169 /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small
170 /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more
171 /// sophisticated implementation could perform jobs concurrently when the server is under low load.
172 ///
173 /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any
174 /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine
175 /// beyond a single thread will require considerable thought.
176 ///
177 /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot
178 /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues
179 /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where
180 /// the job engine could be improved and so CPU utilization improved by better management of concurrency within
181 /// OpenSimulator.
182 /// </remarks>
183 /// <param name="jobType">General classification for the job (e.g. "RezAttachments").</param>
184 /// <param name="callback">Callback for job.</param>
185 /// <param name="obj">Object to pass to callback when run</param>
186 /// <param name="name">Specific name of job (e.g. "RezAttachments for Joe Bloggs"</param>
187 /// <param name="canRunInThisThread">If set to true then the job may be run in ths calling thread.</param>
188 /// <param name="mustNotTimeout">If the true then the job must never timeout.</param>
189 /// <param name="log">If set to true then extra logging is performed.</param>
190 public static void RunJob(
191 string jobType, WaitCallback callback, object obj, string name,
192 bool canRunInThisThread = false, bool mustNotTimeout = false,
193 bool log = false)
194 {
195 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
196 {
197 Culture.SetCurrentCulture();
198 callback(obj);
199 return;
200 }
201
202 if (JobEngine.IsRunning)
203 JobEngine.QueueRequest(name, callback, obj);
204 else if (canRunInThisThread)
205 callback(obj);
206 else if (mustNotTimeout)
207 RunInThread(callback, obj, name, log);
208 else
209 Util.FireAndForget(callback, obj, name);
210 }
211 }
212} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 4561d23..28bba70 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -120,7 +120,7 @@ namespace OpenSim.Framework.Servers.HttpServer
120 for (uint i = 0; i < m_WorkerThreadCount; i++) 120 for (uint i = 0; i < m_WorkerThreadCount; i++)
121 { 121 {
122 m_workerThreads[i] 122 m_workerThreads[i]
123 = Watchdog.StartThread( 123 = WorkManager.StartThread(
124 PoolWorkerJob, 124 PoolWorkerJob,
125 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), 125 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
126 ThreadPriority.Normal, 126 ThreadPriority.Normal,
@@ -130,7 +130,7 @@ namespace OpenSim.Framework.Servers.HttpServer
130 int.MaxValue); 130 int.MaxValue);
131 } 131 }
132 132
133 Watchdog.StartThread( 133 WorkManager.StartThread(
134 this.CheckLongPollThreads, 134 this.CheckLongPollThreads,
135 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), 135 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
136 ThreadPriority.Normal, 136 ThreadPriority.Normal,
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 0f61faf..3be411a 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -339,7 +339,7 @@ namespace OpenSim
339 339
340 IConfig startupConfig = Config.Configs["Startup"]; 340 IConfig startupConfig = Config.Configs["Startup"];
341 if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true)) 341 if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true))
342 Watchdog.JobEngine.Start(); 342 WorkManager.JobEngine.Start();
343 343
344 m_httpServerPort = m_networkServersInfo.HttpListenerPort; 344 m_httpServerPort = m_networkServersInfo.HttpListenerPort;
345 SceneManager.OnRestartSim += HandleRestartRegion; 345 SceneManager.OnRestartSim += HandleRestartRegion;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 87192a0..84ca4bb 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Region.ClientStack.Linden
207 207
208 for (uint i = 0; i < 2; i++) 208 for (uint i = 0; i < 2; i++)
209 { 209 {
210 m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests, 210 m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests,
211 String.Format("InventoryWorkerThread{0}", i), 211 String.Format("InventoryWorkerThread{0}", i),
212 ThreadPriority.Normal, 212 ThreadPriority.Normal,
213 false, 213 false,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs
index 874ddae..6f40b24 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs
@@ -132,7 +132,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
132 132
133 StatsManager.RegisterStat(m_requestsWaitingStat); 133 StatsManager.RegisterStat(m_requestsWaitingStat);
134 134
135 Watchdog.StartThread( 135 WorkManager.StartThread(
136 ProcessRequests, 136 ProcessRequests,
137 string.Format("Incoming Packet Async Handling Engine Thread ({0})", m_udpServer.Scene.Name), 137 string.Format("Incoming Packet Async Handling Engine Thread ({0})", m_udpServer.Scene.Name),
138 ThreadPriority.Normal, 138 ThreadPriority.Normal,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d8cf7a5..2f97516 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -483,7 +483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); 483 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
484 484
485 // This thread will process the packets received that are placed on the packetInbox 485 // This thread will process the packets received that are placed on the packetInbox
486 Watchdog.StartThread( 486 WorkManager.StartThread(
487 IncomingPacketHandler, 487 IncomingPacketHandler,
488 string.Format("Incoming Packets ({0})", Scene.Name), 488 string.Format("Incoming Packets ({0})", Scene.Name),
489 ThreadPriority.Normal, 489 ThreadPriority.Normal,
@@ -499,7 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
499 499
500 base.StartOutbound(); 500 base.StartOutbound();
501 501
502 Watchdog.StartThread( 502 WorkManager.StartThread(
503 OutgoingPacketHandler, 503 OutgoingPacketHandler,
504 string.Format("Outgoing Packets ({0})", Scene.Name), 504 string.Format("Outgoing Packets ({0})", Scene.Name),
505 ThreadPriority.Normal, 505 ThreadPriority.Normal,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
index 2ec1733..1e915c3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
@@ -124,7 +124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
124 124
125 StatsManager.RegisterStat(m_oqreRequestsWaitingStat); 125 StatsManager.RegisterStat(m_oqreRequestsWaitingStat);
126 126
127 Watchdog.StartThread( 127 WorkManager.StartThread(
128 ProcessRequests, 128 ProcessRequests,
129 String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name), 129 String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name),
130 ThreadPriority.Normal, 130 ThreadPriority.Normal,
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 5eca025..fe9a17d 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -964,11 +964,11 @@ namespace OpenSim.Region.CoreModules.Asset
964 case "assets": 964 case "assets":
965 con.Output("Ensuring assets are cached for all scenes."); 965 con.Output("Ensuring assets are cached for all scenes.");
966 966
967 Watchdog.RunInThread(delegate 967 WorkManager.RunInThread(delegate
968 { 968 {
969 int assetReferenceTotal = TouchAllSceneAssets(true); 969 int assetReferenceTotal = TouchAllSceneAssets(true);
970 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); 970 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
971 }, "TouchAllSceneAssets", null); 971 }, null, "TouchAllSceneAssets");
972 972
973 break; 973 break;
974 974
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 9fb8aa5..6dab227 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -431,7 +431,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
431 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 431 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
432 options, ReceivedAllAssets); 432 options, ReceivedAllAssets);
433 433
434 Watchdog.RunInThread(o => ar.Execute(), string.Format("AssetsRequest ({0})", m_scene.Name), null); 434 WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name));
435 } 435 }
436 else 436 else
437 { 437 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
index ce6cdc9..f62e7f4 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
134 134
135 StatsManager.RegisterStat(m_requestsWaitingStat); 135 StatsManager.RegisterStat(m_requestsWaitingStat);
136 136
137 Watchdog.StartThread( 137 WorkManager.StartThread(
138 ProcessRequests, 138 ProcessRequests,
139 string.Format("HG Incoming Scene Object Engine Thread ({0})", Name), 139 string.Format("HG Incoming Scene Object Engine Thread ({0})", Name),
140 ThreadPriority.Normal, 140 ThreadPriority.Normal,
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
index a70261e..3abacbd 100644
--- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.Framework
67 m_timer.Elapsed += ProcessQueue; 67 m_timer.Elapsed += ProcessQueue;
68 m_timer.Start(); 68 m_timer.Start();
69 69
70 //Watchdog.StartThread( 70 //WorkManager.StartThread(
71 // ProcessQueue, 71 // ProcessQueue,
72 // "GridServiceRequestThread", 72 // "GridServiceRequestThread",
73 // ThreadPriority.BelowNormal, 73 // ThreadPriority.BelowNormal,
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index d7ea906..af3700b 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
658 public void Process() 658 public void Process()
659 { 659 {
660 _finished = false; 660 _finished = false;
661 Watchdog.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); 661 WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false);
662 } 662 }
663 663
664 /* 664 /*
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 470ef02..cbe0e37 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -184,12 +184,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
184 // Protect ourselves against the caller subsequently modifying the items list 184 // Protect ourselves against the caller subsequently modifying the items list
185 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); 185 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
186 186
187 Watchdog.RunInThread(delegate 187 WorkManager.RunInThread(delegate
188 { 188 {
189 foreach (InventoryItemBase item in items) 189 foreach (InventoryItemBase item in items)
190 if (!string.IsNullOrEmpty(item.CreatorData)) 190 if (!string.IsNullOrEmpty(item.CreatorData))
191 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 191 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
192 }, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID), null); 192 }, null, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID));
193 } 193 }
194 194
195 return invCol; 195 return invCol;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 3e0c9f3..9c6706f 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -372,7 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so 372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
373 // that users can enter the scene. If we allow the scripts to start in the loop above 373 // that users can enter the scene. If we allow the scripts to start in the loop above
374 // then they significantly increase the time until the OAR finishes loading. 374 // then they significantly increase the time until the OAR finishes loading.
375 Watchdog.RunInThread(o => 375 WorkManager.RunInThread(o =>
376 { 376 {
377 Thread.Sleep(15000); 377 Thread.Sleep(15000);
378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); 378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
@@ -387,7 +387,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
387 387
388 sceneContext.SceneObjects.Clear(); 388 sceneContext.SceneObjects.Clear();
389 } 389 }
390 }, string.Format("ReadArchiveStartScripts (request {0})", m_requestId), null); 390 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
391 391
392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
393 393
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index 924b999..b7d7c26 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
200 m_rootScene.AssetService, m_rootScene.UserAccountService, 200 m_rootScene.AssetService, m_rootScene.UserAccountService,
201 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); 201 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
202 202
203 Watchdog.RunInThread(o => ar.Execute(), "Archive Assets Request", null); 203 WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request");
204 204
205 // CloseArchive() will be called from ReceivedAllAssets() 205 // CloseArchive() will be called from ReceivedAllAssets()
206 } 206 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index ec39bc0..4d99a6e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -227,7 +227,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
227 finally 227 finally
228 { 228 {
229 if (timedOut) 229 if (timedOut)
230 Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", true); 230 WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
231 } 231 }
232 } 232 }
233 233
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
296 296
297 // We want to stop using the asset cache thread asap 297 // We want to stop using the asset cache thread asap
298 // as we now need to do the work of producing the rest of the archive 298 // as we now need to do the work of producing the rest of the archive
299 Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", false); 299 WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
300 } 300 }
301 else 301 else
302 { 302 {
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 78fbefe..767f75f 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -381,7 +381,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
381 381
382// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); 382// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread");
383 383
384 Watchdog.StartThread( 384 WorkManager.StartThread(
385 process, 385 process,
386 string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), 386 string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName),
387 ThreadPriority.BelowNormal, 387 ThreadPriority.BelowNormal,
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 171f066..f7c12d6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1428,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes
1428 } 1428 }
1429 1429
1430 m_heartbeatThread 1430 m_heartbeatThread
1431 = Watchdog.StartThread( 1431 = WorkManager.StartThread(
1432 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1432 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
1433 1433
1434 StartScripts(); 1434 StartScripts();
@@ -1469,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes
1469 // alarms for scenes with many objects. 1469 // alarms for scenes with many objects.
1470 Update(1); 1470 Update(1);
1471 1471
1472 Watchdog.StartThread( 1472 WorkManager.StartThread(
1473 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); 1473 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1474 1474
1475 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1475 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
@@ -1568,10 +1568,10 @@ namespace OpenSim.Region.Framework.Scenes
1568 tmpMS = Util.EnvironmentTickCount(); 1568 tmpMS = Util.EnvironmentTickCount();
1569 m_cleaningTemps = true; 1569 m_cleaningTemps = true;
1570 1570
1571 Watchdog.RunInThread( 1571 WorkManager.RunInThread(
1572 delegate { CleanTempObjects(); m_cleaningTemps = false; }, 1572 delegate { CleanTempObjects(); m_cleaningTemps = false; },
1573 string.Format("CleanTempObjects ({0})", Name), 1573 null,
1574 null); 1574 string.Format("CleanTempObjects ({0})", Name));
1575 1575
1576 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); 1576 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1577 } 1577 }
@@ -1843,7 +1843,7 @@ namespace OpenSim.Region.Framework.Scenes
1843 if (!m_backingup) 1843 if (!m_backingup)
1844 { 1844 {
1845 m_backingup = true; 1845 m_backingup = true;
1846 Watchdog.RunInThread(o => Backup(false), string.Format("BackupWaitCallback ({0})", Name), null); 1846 WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name));
1847 } 1847 }
1848 } 1848 }
1849 1849
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 757ec43..5a35aff 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1228,11 +1228,11 @@ namespace OpenSim.Region.Framework.Scenes
1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call. 1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1229 if (Scene.AttachmentsModule != null) 1229 if (Scene.AttachmentsModule != null)
1230 { 1230 {
1231 Watchdog.RunJob( 1231 WorkManager.RunJob(
1232 "RezAttachments", 1232 "RezAttachments",
1233 o => Scene.AttachmentsModule.RezAttachments(this), 1233 o => Scene.AttachmentsModule.RezAttachments(this),
1234 string.Format("Rez attachments for {0} in {1}", Name, Scene.Name), 1234 null,
1235 null); 1235 string.Format("Rez attachments for {0} in {1}", Name, Scene.Name));
1236 } 1236 }
1237 } 1237 }
1238 else 1238 else
@@ -1254,11 +1254,11 @@ namespace OpenSim.Region.Framework.Scenes
1254 1254
1255 if (attachments.Count > 0) 1255 if (attachments.Count > 0)
1256 { 1256 {
1257 Watchdog.RunJob( 1257 WorkManager.RunJob(
1258 "StartAttachmentScripts", 1258 "StartAttachmentScripts",
1259 o => RestartAttachmentScripts(attachments), 1259 o => RestartAttachmentScripts(attachments),
1260 string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
1261 null, 1260 null,
1261 string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
1262 true); 1262 true);
1263 } 1263 }
1264 } 1264 }
@@ -1815,11 +1815,11 @@ namespace OpenSim.Region.Framework.Scenes
1815 // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region 1815 // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region
1816 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. 1816 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work.
1817 // This may be due to viewer code or it may be something we're not doing properly simulator side. 1817 // This may be due to viewer code or it may be something we're not doing properly simulator side.
1818 Watchdog.RunJob( 1818 WorkManager.RunJob(
1819 "ScheduleAttachmentsForFullUpdate", 1819 "ScheduleAttachmentsForFullUpdate",
1820 o => ScheduleAttachmentsForFullUpdate(), 1820 o => ScheduleAttachmentsForFullUpdate(),
1821 string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name),
1822 null, 1821 null,
1822 string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name),
1823 true); 1823 true);
1824 1824
1825 // m_log.DebugFormat( 1825 // m_log.DebugFormat(
@@ -3375,7 +3375,7 @@ namespace OpenSim.Region.Framework.Scenes
3375 SentInitialDataToClient = true; 3375 SentInitialDataToClient = true;
3376 3376
3377 // Send all scene object to the new client 3377 // Send all scene object to the new client
3378 Watchdog.RunJob("SendInitialDataToClient", delegate 3378 WorkManager.RunJob("SendInitialDataToClient", delegate
3379 { 3379 {
3380// m_log.DebugFormat( 3380// m_log.DebugFormat(
3381// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}", 3381// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}",
@@ -3393,7 +3393,7 @@ namespace OpenSim.Region.Framework.Scenes
3393 if (e != null && e is SceneObjectGroup) 3393 if (e != null && e is SceneObjectGroup)
3394 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 3394 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
3395 } 3395 }
3396 }, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name),null, false, true); 3396 }, null, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), false, true);
3397 } 3397 }
3398 3398
3399 /// <summary> 3399 /// <summary>
@@ -4057,11 +4057,11 @@ namespace OpenSim.Region.Framework.Scenes
4057 // We don't need to worry about a race condition as the job to later start the scripts is also 4057 // We don't need to worry about a race condition as the job to later start the scripts is also
4058 // JobEngine scheduled and so will always occur after this task. 4058 // JobEngine scheduled and so will always occur after this task.
4059 // XXX: This will not be true if JobEngine ever gets more than one thread. 4059 // XXX: This will not be true if JobEngine ever gets more than one thread.
4060 Watchdog.RunJob( 4060 WorkManager.RunJob(
4061 "CopyAttachments", 4061 "CopyAttachments",
4062 o => Scene.AttachmentsModule.CopyAttachments(cAgent, this), 4062 o => Scene.AttachmentsModule.CopyAttachments(cAgent, this),
4063 string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name),
4064 null, 4063 null,
4064 string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name),
4065 true); 4065 true);
4066 } 4066 }
4067 4067
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index e1aaf18..6fe86b2 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
71 m_client = client; 71 m_client = client;
72 m_scene = scene; 72 m_scene = scene;
73 73
74 Watchdog.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); 74 WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true);
75 } 75 }
76 76
77 private void SendServerCommand(string command) 77 private void SendServerCommand(string command)
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
index 9d27386..a1682d2 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
58 58
59 m_listener.Start(50); 59 m_listener.Start(50);
60 60
61 Watchdog.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true); 61 WorkManager.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true);
62 m_baseScene = baseScene; 62 m_baseScene = baseScene;
63 } 63 }
64 64
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
index bdd07e0..6985371 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -359,7 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
359 359
360 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 360 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port);
361 361
362 Watchdog.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); 362 WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false);
363 363
364 // This is the message order recommended by RFC 2812 364 // This is the message order recommended by RFC 2812
365 if (m_password != null) 365 if (m_password != null)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 46a13ab..0f79a10 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -293,7 +293,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
293 { 293 {
294 // The physics simulation should happen independently of the heartbeat loop 294 // The physics simulation should happen independently of the heartbeat loop
295 m_physicsThread 295 m_physicsThread
296 = Watchdog.StartThread( 296 = WorkManager.StartThread(
297 BulletSPluginPhysicsThread, 297 BulletSPluginPhysicsThread,
298 string.Format("{0} ({1})", BulletEngineName, RegionName), 298 string.Format("{0} ({1})", BulletEngineName, RegionName),
299 ThreadPriority.Normal, 299 ThreadPriority.Normal,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 40a05cf..036cb5d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -182,7 +182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
182 { 182 {
183 // Start the thread that will be doing the work 183 // Start the thread that will be doing the work
184 cmdHandlerThread 184 cmdHandlerThread
185 = Watchdog.StartThread( 185 = WorkManager.StartThread(
186 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); 186 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true);
187 } 187 }
188 } 188 }