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);
void StopHttpRequest(uint m_localID, LLUUID m_itemID);
HttpRequestClass GetNextCompletedRequest();
void RemoveCompletedRequest(LLUUID id);
}
}

View File

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

View File

@ -28,6 +28,8 @@
using libsecondlife;
using OpenSim.Region.Environment.Modules;
using System.Collections;
using System.Collections.Generic;
namespace OpenSim.Region.Environment.Interfaces
{
@ -36,9 +38,14 @@ namespace OpenSim.Region.Environment.Interfaces
LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID);
void CloseXMLRPCChannel(LLUUID channelKey);
bool hasRequests();
RPCRequestInfo GetNextRequest();
void RemoteDataReply(string channel, string message_id, string sdata, int idata);
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,13 +184,15 @@ namespace OpenSim.Region.Environment.Modules
public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
{
lock (HttpListLock)
{
HttpRequestClass tmpReq;
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
if(m_pendingRequests != null) {
lock (HttpListLock)
{
tmpReq.Stop();
m_pendingRequests.Remove(m_itemID);
HttpRequestClass tmpReq;
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
{
tmpReq.Stop();
m_pendingRequests.Remove(m_itemID);
}
}
}
}
@ -216,7 +218,6 @@ namespace OpenSim.Region.Environment.Modules
{
if (tmpReq.finished)
{
m_pendingRequests.Remove(luid);
return tmpReq;
}
}
@ -224,6 +225,21 @@ namespace OpenSim.Region.Environment.Modules
}
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.Priority = ThreadPriority.BelowNormal;
httpThread.IsBackground = true;
finished = false;
httpThread.Start();
}

View File

@ -84,8 +84,8 @@ namespace OpenSim.Region.Environment.Modules
m_scene = scene;
m_scene.RegisterModuleInterface<IWorldComm>(this);
m_listenerManager = new ListenerManager();
m_pending = new Queue<ListenerInfo>();
m_scene.EventManager.OnNewClient += NewClient;
m_pending = new Queue<ListenerInfo>();
}
public void PostInitialise()
@ -139,9 +139,12 @@ namespace OpenSim.Region.Environment.Modules
public void DeleteListener(LLUUID itemID)
{
lock (ListLock)
if (m_listenerManager != null)
{
m_listenerManager.DeleteListener(itemID);
lock (ListLock)
{
m_listenerManager.DeleteListener(itemID);
}
}
}
@ -167,14 +170,14 @@ namespace OpenSim.Region.Environment.Modules
// If they are in proximity, then if they are
// 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;
m_scene.Entities.TryGetValue(eb, out sPart);
m_scene.Entities.TryGetValue(li.GetHostID(), out sPart);
// Dont process if this message is from itself!
if (eb.ToString().Equals(sourceItemID) ||
if (li.GetHostID().ToString().Equals(sourceItemID) ||
sPart.UUID.ToString().Equals(sourceItemID))
continue;
@ -196,7 +199,10 @@ namespace OpenSim.Region.Environment.Modules
);
if (isListener != null)
{
m_pending.Enqueue(isListener);
lock (CommListLock)
{
m_pending.Enqueue(isListener);
}
}
}
break;
@ -210,7 +216,10 @@ namespace OpenSim.Region.Environment.Modules
);
if (isListener != null)
{
m_pending.Enqueue(isListener);
lock (CommListLock)
{
m_pending.Enqueue(isListener);
}
}
}
break;
@ -223,14 +232,17 @@ namespace OpenSim.Region.Environment.Modules
);
if (isListener != null)
{
m_pending.Enqueue(isListener);
lock (CommListLock)
{
m_pending.Enqueue(isListener);
}
}
}
break;
case ChatTypeEnum.Broadcast:
ListenerInfo isListen =
m_listenerManager.IsListenerMatch(sourceItemID, eb, channel, name, msg);
m_listenerManager.IsListenerMatch(sourceItemID, li.GetItemID(), channel, name, msg);
if (isListen != null)
{
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
@ -238,19 +250,24 @@ namespace OpenSim.Region.Environment.Modules
);
if (isListener != null)
{
m_pending.Enqueue(isListener);
lock (CommListLock)
{
m_pending.Enqueue(isListener);
}
}
}
break;
}
}
;
}
}
public bool HasMessages()
{
return (m_pending.Count > 0);
if (m_pending != null)
return (m_pending.Count > 0);
else
return false;
}
public ListenerInfo GetNextMessage()
@ -264,6 +281,17 @@ namespace OpenSim.Region.Environment.Modules
return li;
}
public uint PeekNextMessageLocalID()
{
return m_pending.Peek().GetLocalID();
}
public LLUUID PeekNextMessageItemID()
{
return m_pending.Peek().GetItemID();
}
}
// hostID: the ID of the ScenePart
@ -280,8 +308,7 @@ namespace OpenSim.Region.Environment.Modules
m_listeners = new Dictionary<int, ListenerInfo>();
}
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id,
string msg)
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
{
if (m_listeners.Count < m_MaxListeners)
{
@ -410,6 +437,11 @@ namespace OpenSim.Region.Environment.Modules
}
return null;
}
public Dictionary<int, ListenerInfo>.ValueCollection GetListeners()
{
return m_listeners.Values;
}
}
public class ListenerInfo
@ -425,21 +457,20 @@ namespace OpenSim.Region.Environment.Modules
private string m_message; // The message
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,
string message)
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message)
{
Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
}
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id,
string message, LLUUID sourceItemID)
string message, LLUUID sourceItemID)
{
Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
m_sourceItemID = sourceItemID;
}
private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name,
LLUUID id, string message)
LLUUID id, string message)
{
m_handle = handle;
m_channel = channel;
@ -511,5 +542,6 @@ namespace OpenSim.Region.Environment.Modules
{
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 Scene m_scene;
private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
private object XMLRPCListLock = new object();
private string m_name = "XMLRPCModule";
private int RemoteReplyScriptWait = 300;
private int RemoteReplyScriptTimeout = 900;
private int RemoteReplyScriptTimeout = 9000;
private int m_remoteDataPort = 0;
private List<Scene> m_scenes = new List<Scene>();
// <channel id, RPCChannelInfo>
private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
// <channel id, RPCRequestInfo>
private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse;
private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
public void Initialise(Scene scene, IConfigSource config)
{
@ -115,13 +116,15 @@ namespace OpenSim.Region.Environment.Modules
if (IsEnabled())
{
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
// Attach xmlrpc handlers
m_log.Info("[REMOTE_DATA]: " +
"Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort);
BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort);
httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
httpServer.Start();
}
@ -188,18 +191,28 @@ namespace OpenSim.Region.Environment.Modules
return channel;
}
public void DeleteChannel(LLUUID itemID)
// Delete channels based on itemID
// for when a script is deleted
public void DeleteChannels(LLUUID itemID)
{
foreach (RPCChannelInfo li in m_openChannels.Values)
if (m_openChannels != null)
{
ArrayList tmp = new ArrayList();
if (li.GetItemID().Equals(itemID))
lock (XMLRPCListLock)
{
foreach (RPCChannelInfo li in m_openChannels.Values)
{
if (li.GetItemID().Equals(itemID))
{
tmp.Add(itemID);
}
}
m_openChannels.Remove(li.GetChannelID());
return;
System.Collections.IEnumerator tmpEnumerator = tmp.GetEnumerator();
while ( tmpEnumerator.MoveNext() )
m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
}
}
@ -218,15 +231,12 @@ namespace OpenSim.Region.Environment.Modules
RPCRequestInfo rpcInfo;
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);
lock (XMLRPCListLock)
{
m_pendingResponse.Remove(message_key);
}
m_rpcPendingResponses.Remove(message_key);
}
}
@ -248,18 +258,18 @@ namespace OpenSim.Region.Environment.Modules
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
Hashtable requestData = (Hashtable)request.Params[0];
bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") &&
requestData.Contains("StringValue"));
if (GoodXML)
{
LLUUID channel = new LLUUID((string) requestData["Channel"]);
LLUUID channel = new LLUUID((string)requestData["Channel"]);
RPCChannelInfo rpcChanInfo;
if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
{
string intVal = (string) requestData["IntValue"];
string strVal = (string) requestData["StringValue"];
string intVal = (string)requestData["IntValue"];
string strVal = (string)requestData["StringValue"];
RPCRequestInfo rpcInfo;
@ -268,7 +278,7 @@ namespace OpenSim.Region.Environment.Modules
rpcInfo =
new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
intVal);
rpcQueue.Enqueue(rpcInfo);
m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
}
int timeoutCtr = 0;
@ -280,16 +290,20 @@ namespace OpenSim.Region.Environment.Modules
}
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;
}
else
{
response.SetFault(-1, "Script timeout");
lock (XMLRPCListLock)
{
m_pendingResponse.Remove(rpcInfo.GetMessageID());
}
rpcInfo = null;
}
}
else
@ -303,129 +317,365 @@ namespace OpenSim.Region.Environment.Modules
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)
{
foreach (LLUUID luid in m_rpcPending.Keys)
{
RPCRequestInfo tmpReq;
if (m_rpcPending.TryGetValue(luid, out tmpReq))
{
if (!tmpReq.IsProcessed()) return tmpReq;
}
}
}
}
return null;
}
public void RemoveCompletedRequest(LLUUID id)
{
lock (XMLRPCListLock)
{
RPCRequestInfo rpcInfo = rpcQueue.Dequeue();
m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo);
return rpcInfo;
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
*
* Holds details about incoming requests until they are picked
* from the queue by LSLLongCmdHandler
* ***********************************************************/
/**************************************************************
*
* Class RPCRequestInfo
*
* Holds details about incoming requests until they are picked
* from the queue by LSLLongCmdHandler
* ***********************************************************/
public class RPCRequestInfo
{
private string m_StrVal;
private string m_IntVal;
private bool m_processed;
private string m_resp;
private uint m_localID;
private LLUUID m_ItemID;
private LLUUID m_MessageID;
private LLUUID m_ChannelKey;
public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
public class RPCRequestInfo
{
m_localID = localID;
m_StrVal = strVal;
m_IntVal = intVal;
m_ItemID = itemID;
m_ChannelKey = channelKey;
m_MessageID = LLUUID.Random();
m_processed = false;
m_resp = String.Empty;
private string m_StrVal;
private string m_IntVal;
private bool m_processed;
private string m_respStr;
private int m_respInt;
private uint m_localID;
private LLUUID m_ItemID;
private LLUUID m_MessageID;
private LLUUID m_ChannelKey;
public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
{
m_localID = localID;
m_StrVal = strVal;
m_IntVal = intVal;
m_ItemID = itemID;
m_ChannelKey = channelKey;
m_MessageID = LLUUID.Random();
m_processed = false;
m_respStr = String.Empty;
m_respInt = 0;
}
public bool IsProcessed()
{
return m_processed;
}
public LLUUID GetChannelKey()
{
return m_ChannelKey;
}
public void SetProcessed(bool processed)
{
m_processed = processed;
}
public void SetStrRetval(string resp)
{
m_respStr = resp;
}
public string GetStrRetval()
{
return m_respStr;
}
public void SetIntRetval(int resp)
{
m_respInt = resp;
}
public int GetIntRetval()
{
return m_respInt;
}
public uint GetLocalID()
{
return m_localID;
}
public LLUUID GetItemID()
{
return m_ItemID;
}
public string GetStrVal()
{
return m_StrVal;
}
public int GetIntValue()
{
return int.Parse(m_IntVal);
}
public LLUUID GetMessageID()
{
return m_MessageID;
}
}
public bool IsProcessed()
public class RPCChannelInfo
{
return m_processed;
private LLUUID m_itemID;
private uint m_localID;
private LLUUID m_ChannelKey;
public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
{
m_ChannelKey = channelID;
m_localID = localID;
m_itemID = itemID;
}
public LLUUID GetItemID()
{
return m_itemID;
}
public LLUUID GetChannelID()
{
return m_ChannelKey;
}
public uint GetLocalID()
{
return m_localID;
}
}
public LLUUID GetChannelKey()
public class SendRemoteDataRequest
{
return m_ChannelKey;
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;
}
}
public void SetProcessed(bool processed)
{
m_processed = processed;
}
public void SetRetval(string resp)
{
m_resp = resp;
}
public string GetRetval()
{
return m_resp;
}
public uint GetLocalID()
{
return m_localID;
}
public LLUUID GetItemID()
{
return m_ItemID;
}
public string GetStrVal()
{
return m_StrVal;
}
public int GetIntValue()
{
return int.Parse(m_IntVal);
}
public LLUUID GetMessageID()
{
return m_MessageID;
}
}
public class RPCChannelInfo
{
private LLUUID m_itemID;
private uint m_localID;
private LLUUID m_ChannelKey;
public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
{
m_ChannelKey = channelID;
m_localID = localID;
m_itemID = itemID;
}
public LLUUID GetItemID()
{
return m_itemID;
}
public LLUUID GetChannelID()
{
return m_ChannelKey;
}
public uint GetLocalID()
{
return m_localID;
}
}
}
}

View File

@ -2091,6 +2091,10 @@ namespace OpenSim.Region.ScriptEngine.Common
public const int REMOTE_DATA_CHANNEL = 1;
public const int REMOTE_DATA_REQUEST = 2;
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_PHYSICS = 3;

View File

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

View File

@ -125,8 +125,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
comms.DeleteListener(itemID);
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
xmlrpc.DeleteChannel(itemID);
xmlrpc.DeleteChannels(itemID);
xmlrpc.CancelSRDRequests(itemID);
}
#region TIMER
@ -238,24 +240,29 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
// implemented here yet anyway. Should be fixed if/when maxsize
// is supported
object[] resobj = new object[]
if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
{
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
object[] resobj = new object[]
{
httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
};
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
);
httpInfo.Stop();
httpInfo = null;
}
httpInfo = iHttpReq.GetNextCompletedRequest();
}
}
#endregion
#region Check llRemoteData channels
public void CheckXMLRPCRequests()
{
if (m_ScriptEngine.World == null)
@ -265,47 +272,96 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
if (xmlrpc != null)
{
while (xmlrpc.hasRequests())
{
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
//Console.WriteLine("PICKED REQUEST");
RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
while (rInfo != null)
{
if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
{
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
rInfo.GetIntValue(),
rInfo.GetStrVal()
};
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
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()
{
if (m_ScriptEngine.World == null)
return;
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
while (comms.HasMessages())
if (comms != null)
{
ListenerInfo lInfo = comms.GetNextMessage();
//Deliver data to prim's listen handler
object[] resobj = new object[]
while (comms.HasMessages())
{
if (m_ScriptEngine.m_ScriptManager.GetScript(
comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
{
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
};
ListenerInfo lInfo = comms.GetNextMessage();
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
);
//Deliver data to prim's listen handler
object[] resobj = new object[]
{
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
};
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
);
}
}
}
}
#endregion
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
@ -317,4 +373,4 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
private bool _PleaseShutdown = false;
}
}
}

View File

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