From: Michael Osias <mosias@us.ibm.com>

This patch implements the llSendRemoteData command and fixes mantis 552,
and possibly 586.
ThreadPoolClientBranch
Sean Dague 2008-02-19 19:16:21 +00:00
parent 69b1edebf6
commit 530cc24884
10 changed files with 597 additions and 218 deletions

View File

@ -38,5 +38,7 @@ namespace OpenSim.Region.Environment.Interfaces
LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body); LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body);
void StopHttpRequest(uint m_localID, LLUUID m_itemID); void StopHttpRequest(uint m_localID, LLUUID m_itemID);
HttpRequestClass GetNextCompletedRequest(); HttpRequestClass GetNextCompletedRequest();
void RemoveCompletedRequest(LLUUID id);
} }
} }

View File

@ -41,5 +41,8 @@ namespace OpenSim.Region.Environment.Interfaces
void ListenControl(int handle, int active); void ListenControl(int handle, int active);
void ListenRemove(int handle); void ListenRemove(int handle);
void DeleteListener(LLUUID itemID); void DeleteListener(LLUUID itemID);
uint PeekNextMessageLocalID();
LLUUID PeekNextMessageItemID();
} }
} }

View File

@ -28,6 +28,8 @@
using libsecondlife; using libsecondlife;
using OpenSim.Region.Environment.Modules; using OpenSim.Region.Environment.Modules;
using System.Collections;
using System.Collections.Generic;
namespace OpenSim.Region.Environment.Interfaces namespace OpenSim.Region.Environment.Interfaces
{ {
@ -36,9 +38,14 @@ namespace OpenSim.Region.Environment.Interfaces
LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID); LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID);
void CloseXMLRPCChannel(LLUUID channelKey); void CloseXMLRPCChannel(LLUUID channelKey);
bool hasRequests(); bool hasRequests();
RPCRequestInfo GetNextRequest();
void RemoteDataReply(string channel, string message_id, string sdata, int idata); void RemoteDataReply(string channel, string message_id, string sdata, int idata);
bool IsEnabled(); bool IsEnabled();
void DeleteChannel(LLUUID itemID); RPCRequestInfo GetNextCompletedRequest();
void RemoveCompletedRequest(LLUUID id);
void DeleteChannels(LLUUID itemID);
LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata);
SendRemoteDataRequest GetNextCompletedSRDRequest();
void RemoveCompletedSRDRequest(LLUUID id);
void CancelSRDRequests(LLUUID itemID);
} }
} }

View File

@ -184,6 +184,7 @@ namespace OpenSim.Region.Environment.Modules
public void StopHttpRequest(uint m_localID, LLUUID m_itemID) public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
{ {
if(m_pendingRequests != null) {
lock (HttpListLock) lock (HttpListLock)
{ {
HttpRequestClass tmpReq; HttpRequestClass tmpReq;
@ -194,6 +195,7 @@ namespace OpenSim.Region.Environment.Modules
} }
} }
} }
}
/* /*
* TODO * TODO
@ -216,7 +218,6 @@ namespace OpenSim.Region.Environment.Modules
{ {
if (tmpReq.finished) if (tmpReq.finished)
{ {
m_pendingRequests.Remove(luid);
return tmpReq; return tmpReq;
} }
} }
@ -224,6 +225,21 @@ namespace OpenSim.Region.Environment.Modules
} }
return null; return null;
} }
public void RemoveCompletedRequest(LLUUID id)
{
lock (HttpListLock)
{
HttpRequestClass tmpReq;
if (m_pendingRequests.TryGetValue(id, out tmpReq))
{
tmpReq.Stop();
tmpReq = null;
m_pendingRequests.Remove(id);
}
}
}
} }
// //
@ -269,6 +285,7 @@ namespace OpenSim.Region.Environment.Modules
httpThread.Name = "HttpRequestThread"; httpThread.Name = "HttpRequestThread";
httpThread.Priority = ThreadPriority.BelowNormal; httpThread.Priority = ThreadPriority.BelowNormal;
httpThread.IsBackground = true; httpThread.IsBackground = true;
finished = false;
httpThread.Start(); httpThread.Start();
} }

View File

@ -84,8 +84,8 @@ namespace OpenSim.Region.Environment.Modules
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<IWorldComm>(this); m_scene.RegisterModuleInterface<IWorldComm>(this);
m_listenerManager = new ListenerManager(); m_listenerManager = new ListenerManager();
m_pending = new Queue<ListenerInfo>();
m_scene.EventManager.OnNewClient += NewClient; m_scene.EventManager.OnNewClient += NewClient;
m_pending = new Queue<ListenerInfo>();
} }
public void PostInitialise() public void PostInitialise()
@ -138,11 +138,14 @@ namespace OpenSim.Region.Environment.Modules
} }
public void DeleteListener(LLUUID itemID) public void DeleteListener(LLUUID itemID)
{
if (m_listenerManager != null)
{ {
lock (ListLock) lock (ListLock)
{ {
m_listenerManager.DeleteListener(itemID); m_listenerManager.DeleteListener(itemID);
} }
}
} }
@ -167,14 +170,14 @@ namespace OpenSim.Region.Environment.Modules
// If they are in proximity, then if they are // If they are in proximity, then if they are
// listeners, if so add them to the pending queue // listeners, if so add them to the pending queue
foreach (LLUUID eb in m_scene.Entities.Keys) foreach (ListenerInfo li in m_listenerManager.GetListeners())
{ {
EntityBase sPart; EntityBase sPart;
m_scene.Entities.TryGetValue(eb, out sPart); m_scene.Entities.TryGetValue(li.GetHostID(), out sPart);
// Dont process if this message is from itself! // Dont process if this message is from itself!
if (eb.ToString().Equals(sourceItemID) || if (li.GetHostID().ToString().Equals(sourceItemID) ||
sPart.UUID.ToString().Equals(sourceItemID)) sPart.UUID.ToString().Equals(sourceItemID))
continue; continue;
@ -195,10 +198,13 @@ namespace OpenSim.Region.Environment.Modules
sourceItemID, sPart.UUID, channel, name, msg sourceItemID, sPart.UUID, channel, name, msg
); );
if (isListener != null) if (isListener != null)
{
lock (CommListLock)
{ {
m_pending.Enqueue(isListener); m_pending.Enqueue(isListener);
} }
} }
}
break; break;
case ChatTypeEnum.Say: case ChatTypeEnum.Say:
@ -209,10 +215,13 @@ namespace OpenSim.Region.Environment.Modules
sourceItemID, sPart.UUID, channel, name, msg sourceItemID, sPart.UUID, channel, name, msg
); );
if (isListener != null) if (isListener != null)
{
lock (CommListLock)
{ {
m_pending.Enqueue(isListener); m_pending.Enqueue(isListener);
} }
} }
}
break; break;
case ChatTypeEnum.Shout: case ChatTypeEnum.Shout:
@ -222,35 +231,43 @@ namespace OpenSim.Region.Environment.Modules
sourceItemID, sPart.UUID, channel, name, msg sourceItemID, sPart.UUID, channel, name, msg
); );
if (isListener != null) if (isListener != null)
{
lock (CommListLock)
{ {
m_pending.Enqueue(isListener); m_pending.Enqueue(isListener);
} }
} }
}
break; break;
case ChatTypeEnum.Broadcast: case ChatTypeEnum.Broadcast:
ListenerInfo isListen = ListenerInfo isListen =
m_listenerManager.IsListenerMatch(sourceItemID, eb, channel, name, msg); m_listenerManager.IsListenerMatch(sourceItemID, li.GetItemID(), channel, name, msg);
if (isListen != null) if (isListen != null)
{ {
ListenerInfo isListener = m_listenerManager.IsListenerMatch( ListenerInfo isListener = m_listenerManager.IsListenerMatch(
sourceItemID, sPart.UUID, channel, name, msg sourceItemID, sPart.UUID, channel, name, msg
); );
if (isListener != null) if (isListener != null)
{
lock (CommListLock)
{ {
m_pending.Enqueue(isListener); m_pending.Enqueue(isListener);
} }
} }
}
break; break;
} }
} }
;
} }
} }
public bool HasMessages() public bool HasMessages()
{ {
if (m_pending != null)
return (m_pending.Count > 0); return (m_pending.Count > 0);
else
return false;
} }
public ListenerInfo GetNextMessage() public ListenerInfo GetNextMessage()
@ -264,6 +281,17 @@ namespace OpenSim.Region.Environment.Modules
return li; return li;
} }
public uint PeekNextMessageLocalID()
{
return m_pending.Peek().GetLocalID();
}
public LLUUID PeekNextMessageItemID()
{
return m_pending.Peek().GetItemID();
}
} }
// hostID: the ID of the ScenePart // hostID: the ID of the ScenePart
@ -280,8 +308,7 @@ namespace OpenSim.Region.Environment.Modules
m_listeners = new Dictionary<int, ListenerInfo>(); m_listeners = new Dictionary<int, ListenerInfo>();
} }
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
string msg)
{ {
if (m_listeners.Count < m_MaxListeners) if (m_listeners.Count < m_MaxListeners)
{ {
@ -410,6 +437,11 @@ namespace OpenSim.Region.Environment.Modules
} }
return null; return null;
} }
public Dictionary<int, ListenerInfo>.ValueCollection GetListeners()
{
return m_listeners.Values;
}
} }
public class ListenerInfo public class ListenerInfo
@ -425,8 +457,7 @@ namespace OpenSim.Region.Environment.Modules
private string m_message; // The message private string m_message; // The message
private bool m_active; // Listener is active or not private bool m_active; // Listener is active or not
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message)
string message)
{ {
Initialise(localID, handle, ItemID, hostID, channel, name, id, message); Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
} }
@ -511,5 +542,6 @@ namespace OpenSim.Region.Environment.Modules
{ {
return m_id; return m_id;
} }
} }
} }

View File

@ -78,19 +78,20 @@ namespace OpenSim.Region.Environment.Modules
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene; private Scene m_scene;
private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
private object XMLRPCListLock = new object(); private object XMLRPCListLock = new object();
private string m_name = "XMLRPCModule"; private string m_name = "XMLRPCModule";
private int RemoteReplyScriptWait = 300; private int RemoteReplyScriptWait = 300;
private int RemoteReplyScriptTimeout = 900; private int RemoteReplyScriptTimeout = 9000;
private int m_remoteDataPort = 0; private int m_remoteDataPort = 0;
private List<Scene> m_scenes = new List<Scene>(); private List<Scene> m_scenes = new List<Scene>();
// <channel id, RPCChannelInfo> // <channel id, RPCChannelInfo>
private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
// <channel id, RPCRequestInfo> private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse; private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
{ {
@ -115,7 +116,9 @@ namespace OpenSim.Region.Environment.Modules
if (IsEnabled()) if (IsEnabled())
{ {
m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
m_pendingResponse = new Dictionary<LLUUID, RPCRequestInfo>(); m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>();
m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>();
m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>();
// Start http server // Start http server
// Attach xmlrpc handlers // Attach xmlrpc handlers
@ -188,18 +191,28 @@ namespace OpenSim.Region.Environment.Modules
return channel; return channel;
} }
public void DeleteChannel(LLUUID itemID) // Delete channels based on itemID
// for when a script is deleted
public void DeleteChannels(LLUUID itemID)
{ {
if (m_openChannels != null)
{
ArrayList tmp = new ArrayList();
lock (XMLRPCListLock)
{
foreach (RPCChannelInfo li in m_openChannels.Values) foreach (RPCChannelInfo li in m_openChannels.Values)
{ {
if (li.GetItemID().Equals(itemID)) if (li.GetItemID().Equals(itemID))
{ {
tmp.Add(itemID);
}
}
m_openChannels.Remove(li.GetChannelID()); System.Collections.IEnumerator tmpEnumerator = tmp.GetEnumerator();
return; while ( tmpEnumerator.MoveNext() )
m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
} }
} }
@ -218,15 +231,12 @@ namespace OpenSim.Region.Environment.Modules
RPCRequestInfo rpcInfo; RPCRequestInfo rpcInfo;
LLUUID message_key = new LLUUID(message_id); LLUUID message_key = new LLUUID(message_id);
if (m_pendingResponse.TryGetValue(message_key, out rpcInfo)) if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo))
{ {
rpcInfo.SetRetval(sdata); rpcInfo.SetStrRetval(sdata);
rpcInfo.SetIntRetval(idata);
rpcInfo.SetProcessed(true); rpcInfo.SetProcessed(true);
m_rpcPendingResponses.Remove(message_key);
lock (XMLRPCListLock)
{
m_pendingResponse.Remove(message_key);
}
} }
} }
@ -268,7 +278,7 @@ namespace OpenSim.Region.Environment.Modules
rpcInfo = rpcInfo =
new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
intVal); intVal);
rpcQueue.Enqueue(rpcInfo); m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
} }
int timeoutCtr = 0; int timeoutCtr = 0;
@ -280,16 +290,20 @@ namespace OpenSim.Region.Environment.Modules
} }
if (rpcInfo.IsProcessed()) if (rpcInfo.IsProcessed())
{ {
response.Value = rpcInfo.GetRetval(); Hashtable param = new Hashtable();
param["StringValue"] = rpcInfo.GetStrRetval();
param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval());
ArrayList parameters = new ArrayList();
parameters.Add(param);
response.Value = parameters;
rpcInfo = null; rpcInfo = null;
} }
else else
{ {
response.SetFault(-1, "Script timeout"); response.SetFault(-1, "Script timeout");
lock (XMLRPCListLock) rpcInfo = null;
{
m_pendingResponse.Remove(rpcInfo.GetMessageID());
}
} }
} }
else else
@ -303,20 +317,112 @@ namespace OpenSim.Region.Environment.Modules
public bool hasRequests() public bool hasRequests()
{ {
return (rpcQueue.Count > 0); lock (XMLRPCListLock)
{
if (m_rpcPending != null)
return (m_rpcPending.Count > 0);
else
return false;
}
} }
public RPCRequestInfo GetNextRequest() public RPCRequestInfo GetNextCompletedRequest()
{
if (m_rpcPending != null)
{ {
lock (XMLRPCListLock) lock (XMLRPCListLock)
{ {
RPCRequestInfo rpcInfo = rpcQueue.Dequeue(); foreach (LLUUID luid in m_rpcPending.Keys)
m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo); {
return rpcInfo; RPCRequestInfo tmpReq;
if (m_rpcPending.TryGetValue(luid, out tmpReq))
{
if (!tmpReq.IsProcessed()) return tmpReq;
}
}
}
}
return null;
}
public void RemoveCompletedRequest(LLUUID id)
{
lock (XMLRPCListLock)
{
RPCRequestInfo tmp;
if (m_rpcPending.TryGetValue(id, out tmp))
{
m_rpcPending.Remove(id);
m_rpcPendingResponses.Add(id, tmp);
}
else
{
Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST");
} }
} }
} }
public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
{
SendRemoteDataRequest req = new SendRemoteDataRequest(
localID, itemID, channel, dest, idata, sdata
);
m_pendingSRDResponses.Add(req.GetReqID(), req);
return req.process();
}
public SendRemoteDataRequest GetNextCompletedSRDRequest()
{
if (m_pendingSRDResponses != null)
{
lock (XMLRPCListLock)
{
foreach (LLUUID luid in m_pendingSRDResponses.Keys)
{
SendRemoteDataRequest tmpReq;
if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
{
if (tmpReq.finished)
return tmpReq;
}
}
}
}
return null;
}
public void RemoveCompletedSRDRequest(LLUUID id)
{
lock (XMLRPCListLock)
{
SendRemoteDataRequest tmpReq;
if (m_pendingSRDResponses.TryGetValue(id, out tmpReq))
{
m_pendingSRDResponses.Remove(id);
}
}
}
public void CancelSRDRequests(LLUUID itemID)
{
if (m_pendingSRDResponses != null)
{
lock (XMLRPCListLock)
{
foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values)
{
if (li.m_itemID.Equals(itemID))
m_pendingSRDResponses.Remove(li.GetReqID());
}
}
}
}
}
/************************************************************** /**************************************************************
* *
* Class RPCRequestInfo * Class RPCRequestInfo
@ -330,7 +436,8 @@ namespace OpenSim.Region.Environment.Modules
private string m_StrVal; private string m_StrVal;
private string m_IntVal; private string m_IntVal;
private bool m_processed; private bool m_processed;
private string m_resp; private string m_respStr;
private int m_respInt;
private uint m_localID; private uint m_localID;
private LLUUID m_ItemID; private LLUUID m_ItemID;
private LLUUID m_MessageID; private LLUUID m_MessageID;
@ -345,7 +452,8 @@ namespace OpenSim.Region.Environment.Modules
m_ChannelKey = channelKey; m_ChannelKey = channelKey;
m_MessageID = LLUUID.Random(); m_MessageID = LLUUID.Random();
m_processed = false; m_processed = false;
m_resp = String.Empty; m_respStr = String.Empty;
m_respInt = 0;
} }
public bool IsProcessed() public bool IsProcessed()
@ -363,16 +471,24 @@ namespace OpenSim.Region.Environment.Modules
m_processed = processed; m_processed = processed;
} }
public void SetRetval(string resp) public void SetStrRetval(string resp)
{ {
m_resp = resp; m_respStr = resp;
} }
public string GetRetval() public string GetStrRetval()
{ {
return m_resp; return m_respStr;
}
public void SetIntRetval(int resp)
{
m_respInt = resp;
} }
public int GetIntRetval()
{
return m_respInt;
}
public uint GetLocalID() public uint GetLocalID()
{ {
return m_localID; return m_localID;
@ -428,4 +544,138 @@ namespace OpenSim.Region.Environment.Modules
} }
} }
public class SendRemoteDataRequest
{
public LLUUID reqID;
public string destURL;
public string channel;
public string sdata;
public int idata;
public bool finished;
public string response_sdata;
public int response_idata;
public XmlRpcRequest request;
private Thread httpThread;
public LLUUID m_itemID;
public uint m_localID;
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
{
this.channel = channel;
this.destURL = dest;
this.idata = idata;
this.sdata = sdata;
m_itemID = itemID;
m_localID = localID;
reqID = LLUUID.Random();
}
public LLUUID process()
{
httpThread = new Thread(SendRequest);
httpThread.Name = "HttpRequestThread";
httpThread.Priority = ThreadPriority.BelowNormal;
httpThread.IsBackground = true;
finished = false;
httpThread.Start();
return reqID;
}
/*
* TODO: More work on the response codes. Right now
* returning 200 for success or 499 for exception
*/
public void SendRequest()
{
Hashtable param = new Hashtable();
// Check if channel is an LLUUID
// if not, use as method name
LLUUID parseUID;
string mName = "llRemoteData";
if( (channel != null) && (channel != "") )
if( !LLUUID.TryParse(channel, out parseUID) )
mName = channel;
else
param["Channel"] = channel;
param["StringValue"] = sdata;
param["IntValue"] = Convert.ToString(idata);
ArrayList parameters = new ArrayList();
parameters.Add(param);
XmlRpcRequest req = new XmlRpcRequest(mName, parameters);
try
{
XmlRpcResponse resp = req.Send(destURL, 30000);
if (resp != null)
{
Hashtable respParms;
if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) {
respParms = (Hashtable)resp.Value;
}
else {
ArrayList respData = (ArrayList)resp.Value;
respParms = (Hashtable)respData[0];
}
if (respParms != null)
{
if (respParms.Contains("StringValue"))
{
sdata = (string)respParms["StringValue"];
}
if (respParms.Contains("IntValue"))
{
idata = Convert.ToInt32((string)respParms["IntValue"]);
}
if (respParms.Contains("faultString"))
{
sdata = (string)respParms["faultString"];
}
if (respParms.Contains("faultCode"))
{
idata = Convert.ToInt32(respParms["faultCode"]);
}
}
}
}
catch (System.Net.WebException we)
{
sdata = we.Message;
m_log.Warn("[SendRemoteDataRequest]: Request failed");
m_log.Warn(we.StackTrace);
}
finished = true;
}
public void Stop()
{
try
{
httpThread.Abort();
}
catch (Exception)
{
}
}
public LLUUID GetReqID()
{
return reqID;
}
}
} }

View File

@ -2091,6 +2091,10 @@ namespace OpenSim.Region.ScriptEngine.Common
public const int REMOTE_DATA_CHANNEL = 1; public const int REMOTE_DATA_CHANNEL = 1;
public const int REMOTE_DATA_REQUEST = 2; public const int REMOTE_DATA_REQUEST = 2;
public const int REMOTE_DATA_REPLY = 3; public const int REMOTE_DATA_REPLY = 3;
public const int HTTP_METHOD = 0;
public const int HTTP_MIMETYPE = 1;
public const int HTTP_BODY_MAXLENGTH = 2;
public const int HTTP_VERIFY_CERT = 3;
public const int PRIM_MATERIAL = 2; public const int PRIM_MATERIAL = 2;
public const int PRIM_PHYSICS = 3; public const int PRIM_PHYSICS = 3;

View File

@ -2880,8 +2880,8 @@ namespace OpenSim.Region.ScriptEngine.Common
public string llSendRemoteData(string channel, string dest, int idata, string sdata) public string llSendRemoteData(string channel, string dest, int idata, string sdata)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
NotImplemented("llSendRemoteData"); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
return String.Empty; return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString();
} }
public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)

View File

@ -125,7 +125,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
comms.DeleteListener(itemID); comms.DeleteListener(itemID);
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
xmlrpc.DeleteChannel(itemID); xmlrpc.DeleteChannels(itemID);
xmlrpc.CancelSRDRequests(itemID);
} }
@ -238,6 +240,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// implemented here yet anyway. Should be fixed if/when maxsize // implemented here yet anyway. Should be fixed if/when maxsize
// is supported // is supported
if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
{
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
object[] resobj = new object[] object[] resobj = new object[]
{ {
httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
@ -247,15 +252,17 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
); );
httpInfo.Stop(); }
httpInfo = null;
httpInfo = iHttpReq.GetNextCompletedRequest(); httpInfo = iHttpReq.GetNextCompletedRequest();
} }
} }
#endregion #endregion
#region Check llRemoteData channels
public void CheckXMLRPCRequests() public void CheckXMLRPCRequests()
{ {
if (m_ScriptEngine.World == null) if (m_ScriptEngine.World == null)
@ -265,10 +272,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
if (xmlrpc != null) if (xmlrpc != null)
{ {
while (xmlrpc.hasRequests()) RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
while (rInfo != null)
{ {
RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
//Console.WriteLine("PICKED REQUEST"); {
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
//Deliver data to prim's remote_data handler //Deliver data to prim's remote_data handler
object[] resobj = new object[] object[] resobj = new object[]
@ -280,9 +290,45 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
); );
}
rInfo = xmlrpc.GetNextCompletedRequest();
}
SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
while (srdInfo != null)
{
if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null)
{
xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty,
srdInfo.idata,
srdInfo.sdata
};
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj
);
}
srdInfo = xmlrpc.GetNextCompletedSRDRequest();
}
} }
} }
}
#endregion
#region Check llListeners
public void CheckListeners() public void CheckListeners()
{ {
@ -290,7 +336,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
return; return;
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
if (comms != null)
{
while (comms.HasMessages()) while (comms.HasMessages())
{
if (m_ScriptEngine.m_ScriptManager.GetScript(
comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
{ {
ListenerInfo lInfo = comms.GetNextMessage(); ListenerInfo lInfo = comms.GetNextMessage();
@ -304,7 +355,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
); );
} }
} }
}
}
#endregion
/// <summary> /// <summary>
/// If set to true then threads and stuff should try to make a graceful exit /// If set to true then threads and stuff should try to make a graceful exit

View File

@ -67,6 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
private static bool PrivateThread; private static bool PrivateThread;
private int LoadUnloadMaxQueueSize; private int LoadUnloadMaxQueueSize;
private Object scriptLock = new Object();
// Load/Unload structure // Load/Unload structure
private struct LUStruct private struct LUStruct
@ -304,7 +305,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
//ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID);
IScript Script = GetScript(localID, itemID); IScript Script = GetScript(localID, itemID);
if (Script == null) if (Script == null)
{
return; return;
}
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined //cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
///#if DEBUG ///#if DEBUG
/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); /// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
@ -330,6 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
} }
public IScript GetScript(uint localID, LLUUID itemID) public IScript GetScript(uint localID, LLUUID itemID)
{
lock (scriptLock)
{ {
if (Scripts.ContainsKey(localID) == false) if (Scripts.ContainsKey(localID) == false)
return null; return null;
@ -342,11 +347,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// Get script // Get script
IScript Script; IScript Script;
Obj.TryGetValue(itemID, out Script); Obj.TryGetValue(itemID, out Script);
return Script; return Script;
} }
}
public void SetScript(uint localID, LLUUID itemID, IScript Script) public void SetScript(uint localID, LLUUID itemID, IScript Script)
{
lock (scriptLock)
{ {
// Create object if it doesn't exist // Create object if it doesn't exist
if (Scripts.ContainsKey(localID) == false) if (Scripts.ContainsKey(localID) == false)
@ -363,6 +370,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// Add to object // Add to object
Obj.Add(itemID, Script); Obj.Add(itemID, Script);
} }
}
public void RemoveScript(uint localID, LLUUID itemID) public void RemoveScript(uint localID, LLUUID itemID)
{ {