diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index c3e1a79f94..e488b380e7 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -33,8 +33,11 @@ using log4net; using HttpServer; using OpenSim.Framework; + +/* namespace OpenSim.Framework.Servers.HttpServer { + public class PollServiceRequestManager { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -156,3 +159,203 @@ namespace OpenSim.Framework.Servers.HttpServer } } } + */ + +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace OpenSim.Framework.Servers.HttpServer +{ + public class PollServiceRequestManager + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private readonly BaseHttpServer m_server; + + private BlockingQueue m_requests = new BlockingQueue(); + private static Queue m_retry_requests = new Queue(); + + private uint m_WorkerThreadCount = 0; + private Thread[] m_workerThreads; + private Thread m_retrysThread; + + private bool m_running = true; + + private int m_timeout = 250; + + public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) + { + m_server = pSrv; + m_WorkerThreadCount = pWorkerThreadCount; + m_workerThreads = new Thread[m_WorkerThreadCount]; + + //startup worker threads + for (uint i = 0; i < m_WorkerThreadCount; i++) + { + m_workerThreads[i] + = Watchdog.StartThread( + poolWorkerJob, + String.Format("PollServiceWorkerThread{0}", i), + ThreadPriority.Normal, + false, + true, + int.MaxValue); + } + + m_retrysThread = Watchdog.StartThread( + this.CheckRetries, + "PollServiceWatcherThread", + ThreadPriority.Normal, + false, + true, + 1000 * 60 * 10); + } + + + private void ReQueueEvent(PollServiceHttpRequest req) + { + if (m_running) + { + lock (m_retry_requests) + m_retry_requests.Enqueue(req); + } + } + + public void Enqueue(PollServiceHttpRequest req) + { + if (m_running) + m_requests.Enqueue(req); + } + + private void CheckRetries() + { + while (m_running) + { + Thread.Sleep(100); // let the world move + Watchdog.UpdateThread(); + lock (m_retry_requests) + { + while (m_retry_requests.Count > 0 && m_running) + Enqueue(m_retry_requests.Dequeue()); + } + } + } + + ~PollServiceRequestManager() + { + m_running = false; + m_timeout = -10000; // cause all to expire + Thread.Sleep(1000); // let the world move + + foreach (Thread t in m_workerThreads) + { + try + { + t.Abort(); + } + catch + { + } + } + + try + { + foreach (PollServiceHttpRequest req in m_retry_requests) + { + m_server.DoHTTPGruntWork( + req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + } + catch + { + } + + PollServiceHttpRequest wreq; + m_retry_requests.Clear(); + + while (m_requests.Count() > 0) + { + try + { + wreq = m_requests.Dequeue(0); + m_server.DoHTTPGruntWork( + wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(wreq.HttpContext, wreq.Request), wreq.HttpContext)); + } + catch + { + } + } + + m_requests.Clear(); + } + + // work threads + + private void poolWorkerJob() + { + PollServiceHttpRequest req; + StreamReader str; + + while (true) + { + req = m_requests.Dequeue(5000); + + Watchdog.UpdateThread(); + if (req != null) + { + try + { + if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) + { + try + { + str = new StreamReader(req.Request.Body); + } + catch (System.ArgumentException) + { + // Stream was not readable means a child agent + // was closed due to logout, leaving the + // Event Queue request orphaned. + continue; + } + + try + { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); + m_server.DoHTTPGruntWork(responsedata, + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + { + // Ignore it, no need to reply + } + + str.Close(); + + } + else + { + if ((Environment.TickCount - req.RequestTime) > m_timeout) + { + m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), + new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); + } + else + { + ReQueueEvent(req); + } + } + } + catch (Exception e) + { + m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); + } + } + } + } + } +} + diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index b39185fba9..7cd27e5290 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs @@ -25,6 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* Ubit work moved to PollServiceRequestManager + using System; using System.Collections; using System.Collections.Generic; @@ -128,3 +130,4 @@ namespace OpenSim.Framework.Servers.HttpServer } } } +*/ \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 357c2af421..6215526794 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -352,9 +352,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat UUID fromAgentID, string fromName, ChatTypeEnum type, string message, ChatSourceType src) { - // don't send llRegionSay to child agents. Send normal chat because you - // can't talk across sim borders if it's not done - if (type == ChatTypeEnum.Broadcast && presence.IsChildAgent) return false; + // don't send chat to child agents + if (presence.IsChildAgent) return false; Vector3 fromRegionPos = fromPos + regionPos; Vector3 toRegionPos = presence.AbsolutePosition + diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 42844440c1..5974112b4b 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Land * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L); - m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); + //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); return parcelMax; } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 286c7f0721..6c72324ba4 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -302,6 +302,7 @@ namespace OpenSim.Region.Physics.OdePlugin // split static geometry collision into a grid as before private IntPtr[,] staticPrimspace; + private IntPtr[] staticPrimspaceOffRegion; public Object OdeLock; private static Object SimulationLock; @@ -551,6 +552,7 @@ namespace OpenSim.Region.Physics.OdePlugin // create all spaces now int i, j; IntPtr newspace; + for (i = 0; i < spaceGridMaxX; i++) for (j = 0; j < spaceGridMaxY; j++) { @@ -573,6 +575,29 @@ namespace OpenSim.Region.Physics.OdePlugin // let this now be real maximum values spaceGridMaxX--; spaceGridMaxY--; + + // create 4 off world spaces (x<0,x>max,y<0,y>max) + staticPrimspaceOffRegion = new IntPtr[4]; + + for (i = 0; i < 4; i++) + { + newspace = d.HashSpaceCreate(StaticSpace); + d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); + waitForSpaceUnlock(newspace); + d.SpaceSetSublevel(newspace, 2); + d.HashSpaceSetLevels(newspace, -2, 8); + d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | + CollisionCategories.Geom | + CollisionCategories.Land | + CollisionCategories.Water | + CollisionCategories.Phantom | + CollisionCategories.VolumeDtc + )); + d.GeomSetCollideBits(newspace, 0); + + staticPrimspaceOffRegion[i] = newspace; + } + m_lastframe = DateTime.UtcNow; } @@ -1650,20 +1675,22 @@ namespace OpenSim.Region.Physics.OdePlugin public IntPtr calculateSpaceForGeom(Vector3 pos) { int x, y; + + if (pos.X < 0) + return staticPrimspaceOffRegion[0]; + + if (pos.Y < 0) + return staticPrimspaceOffRegion[2]; + x = (int)(pos.X * spacesPerMeter); - if (x < 0) - x = 0; - else if (x > spaceGridMaxX) - x = spaceGridMaxX; - + if (x > spaceGridMaxX) + return staticPrimspaceOffRegion[1]; + y = (int)(pos.Y * spacesPerMeter); - if (y < 0) - y = 0; - else if (y >spaceGridMaxY) - y = spaceGridMaxY; + if (y > spaceGridMaxY) + return staticPrimspaceOffRegion[3]; - IntPtr tmpSpace = staticPrimspace[x, y]; - return tmpSpace; + return staticPrimspace[x, y]; } #endregion