aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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 }