Updated svn properties.

ThreadPoolClientBranch
Jeff Ames 2008-02-02 07:13:37 +00:00
parent b089ccfa3d
commit b1a6f4821b
10 changed files with 909 additions and 908 deletions

View File

@ -1,313 +1,313 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
/// </summary>
public class AsyncLSLCommandManager : iScriptEngineFunctionModule
{
private Thread cmdHandlerThread;
private int cmdHandlerThreadCycleSleepms;
private ScriptEngine m_ScriptEngine;
public AsyncLSLCommandManager(ScriptEngine _ScriptEngine)
{
m_ScriptEngine = _ScriptEngine;
ReadConfig();
// Start the thread that will be doing the work
cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
cmdHandlerThread.Name = "CmdHandlerThread";
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
cmdHandlerThread.IsBackground = true;
cmdHandlerThread.Start();
}
public void ReadConfig()
{
cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 50);
}
~AsyncLSLCommandManager()
{
// Shut down thread
try
{
if (cmdHandlerThread != null)
{
if (cmdHandlerThread.IsAlive == true)
{
cmdHandlerThread.Abort();
cmdHandlerThread.Join();
}
}
}
catch
{
}
}
private void CmdHandlerThreadLoop()
{
while (true)
{
// Check timers
CheckTimerEvents();
Thread.Sleep(25);
// Check HttpRequests
CheckHttpRequests();
Thread.Sleep(25);
// Check XMLRPCRequests
CheckXMLRPCRequests();
Thread.Sleep(25);
// Check Listeners
CheckListeners();
Thread.Sleep(25);
// Sleep before next cycle
//Thread.Sleep(cmdHandlerThreadCycleSleepms);
}
}
/// <summary>
/// Remove a specific script (and all its pending commands)
/// </summary>
/// <param name="m_localID"></param>
/// <param name="m_itemID"></param>
public void RemoveScript(uint localID, LLUUID itemID)
{
// Remove a specific script
// Remove from: Timers
UnSetTimerEvents(localID, itemID);
// Remove from: HttpRequest
IHttpRequests iHttpReq =
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
iHttpReq.StopHttpRequest(localID, itemID);
}
#region TIMER
//
// TIMER
//
private class TimerClass
{
public uint localID;
public LLUUID itemID;
public double interval;
public DateTime next;
}
private List<TimerClass> Timers = new List<TimerClass>();
private object TimerListLock = new object();
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
{
Console.WriteLine("SetTimerEvent");
// Always remove first, in case this is a re-set
UnSetTimerEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
TimerClass ts = new TimerClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = sec;
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
lock (TimerListLock)
{
Timers.Add(ts);
}
}
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (TimerListLock)
{
List<TimerClass> NewTimers = new List<TimerClass>();
foreach (TimerClass ts in Timers)
{
if (ts.localID != m_localID && ts.itemID != m_itemID)
{
NewTimers.Add(ts);
}
}
Timers.Clear();
Timers = NewTimers;
}
}
public void CheckTimerEvents()
{
// Nothing to do here?
if (Timers.Count == 0)
return;
lock (TimerListLock)
{
// Go through all timers
foreach (TimerClass ts in Timers)
{
// Time has passed?
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
{
// Add it to queue
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
new object[] {});
// set next interval
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
}
}
} // lock
}
#endregion
#region HTTP REQUEST
public void CheckHttpRequests()
{
if (m_ScriptEngine.World == null)
return;
IHttpRequests iHttpReq =
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
HttpRequestClass httpInfo = null;
if (iHttpReq != null)
httpInfo = iHttpReq.GetNextCompletedRequest();
while (httpInfo != null)
{
//Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
// Deliver data to prim's remote_data handler
//
// TODO: Returning null for metadata, since the lsl function
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
// implemented here yet anyway. Should be fixed if/when maxsize
// is supported
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
);
httpInfo.Stop();
httpInfo = null;
httpInfo = iHttpReq.GetNextCompletedRequest();
}
}
#endregion
public void CheckXMLRPCRequests()
{
if (m_ScriptEngine.World == null)
return;
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
while (xmlrpc.hasRequests())
{
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
//Console.WriteLine("PICKED REQUEST");
//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
);
}
}
}
public void CheckListeners()
{
if (m_ScriptEngine.World == null)
return;
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
while (comms.HasMessages())
{
ListenerInfo lInfo = comms.GetNextMessage();
//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
);
}
}
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
/// </summary>
public class AsyncLSLCommandManager : iScriptEngineFunctionModule
{
private Thread cmdHandlerThread;
private int cmdHandlerThreadCycleSleepms;
private ScriptEngine m_ScriptEngine;
public AsyncLSLCommandManager(ScriptEngine _ScriptEngine)
{
m_ScriptEngine = _ScriptEngine;
ReadConfig();
// Start the thread that will be doing the work
cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
cmdHandlerThread.Name = "CmdHandlerThread";
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
cmdHandlerThread.IsBackground = true;
cmdHandlerThread.Start();
}
public void ReadConfig()
{
cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 50);
}
~AsyncLSLCommandManager()
{
// Shut down thread
try
{
if (cmdHandlerThread != null)
{
if (cmdHandlerThread.IsAlive == true)
{
cmdHandlerThread.Abort();
cmdHandlerThread.Join();
}
}
}
catch
{
}
}
private void CmdHandlerThreadLoop()
{
while (true)
{
// Check timers
CheckTimerEvents();
Thread.Sleep(25);
// Check HttpRequests
CheckHttpRequests();
Thread.Sleep(25);
// Check XMLRPCRequests
CheckXMLRPCRequests();
Thread.Sleep(25);
// Check Listeners
CheckListeners();
Thread.Sleep(25);
// Sleep before next cycle
//Thread.Sleep(cmdHandlerThreadCycleSleepms);
}
}
/// <summary>
/// Remove a specific script (and all its pending commands)
/// </summary>
/// <param name="m_localID"></param>
/// <param name="m_itemID"></param>
public void RemoveScript(uint localID, LLUUID itemID)
{
// Remove a specific script
// Remove from: Timers
UnSetTimerEvents(localID, itemID);
// Remove from: HttpRequest
IHttpRequests iHttpReq =
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
iHttpReq.StopHttpRequest(localID, itemID);
}
#region TIMER
//
// TIMER
//
private class TimerClass
{
public uint localID;
public LLUUID itemID;
public double interval;
public DateTime next;
}
private List<TimerClass> Timers = new List<TimerClass>();
private object TimerListLock = new object();
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
{
Console.WriteLine("SetTimerEvent");
// Always remove first, in case this is a re-set
UnSetTimerEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
TimerClass ts = new TimerClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = sec;
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
lock (TimerListLock)
{
Timers.Add(ts);
}
}
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (TimerListLock)
{
List<TimerClass> NewTimers = new List<TimerClass>();
foreach (TimerClass ts in Timers)
{
if (ts.localID != m_localID && ts.itemID != m_itemID)
{
NewTimers.Add(ts);
}
}
Timers.Clear();
Timers = NewTimers;
}
}
public void CheckTimerEvents()
{
// Nothing to do here?
if (Timers.Count == 0)
return;
lock (TimerListLock)
{
// Go through all timers
foreach (TimerClass ts in Timers)
{
// Time has passed?
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
{
// Add it to queue
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
new object[] {});
// set next interval
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
}
}
} // lock
}
#endregion
#region HTTP REQUEST
public void CheckHttpRequests()
{
if (m_ScriptEngine.World == null)
return;
IHttpRequests iHttpReq =
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
HttpRequestClass httpInfo = null;
if (iHttpReq != null)
httpInfo = iHttpReq.GetNextCompletedRequest();
while (httpInfo != null)
{
//Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
// Deliver data to prim's remote_data handler
//
// TODO: Returning null for metadata, since the lsl function
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
// implemented here yet anyway. Should be fixed if/when maxsize
// is supported
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
);
httpInfo.Stop();
httpInfo = null;
httpInfo = iHttpReq.GetNextCompletedRequest();
}
}
#endregion
public void CheckXMLRPCRequests()
{
if (m_ScriptEngine.World == null)
return;
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
while (xmlrpc.hasRequests())
{
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
//Console.WriteLine("PICKED REQUEST");
//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
);
}
}
}
public void CheckListeners()
{
if (m_ScriptEngine.World == null)
return;
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
while (comms.HasMessages())
{
ListenerInfo lInfo = comms.GetNextMessage();
//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
);
}
}
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}

View File

@ -1,314 +1,314 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Environment.Scenes.Scripting;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class
/// </summary>
public class EventQueueThreadClass: iScriptEngineFunctionModule
{
/// <summary>
/// How many ms to sleep if queue is empty
/// </summary>
private int nothingToDoSleepms;// = 50;
private ThreadPriority MyThreadPriority;
public long LastExecutionStarted;
public bool InExecution = false;
public bool KillCurrentScript = false;
private EventQueueManager eventQueueManager;
public Thread EventQueueThread;
private static int ThreadCount = 0;
private string ScriptEngineName = "ScriptEngine.Common";
public EventQueueThreadClass(EventQueueManager eqm)
{
eventQueueManager = eqm;
ReadConfig();
Start();
}
~EventQueueThreadClass()
{
Stop();
}
public void ReadConfig()
{
ScriptEngineName = eventQueueManager.m_ScriptEngine.ScriptEngineName;
nothingToDoSleepms = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
// Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
switch (pri.ToLower())
{
case "lowest":
MyThreadPriority = ThreadPriority.Lowest;
break;
case "belownormal":
MyThreadPriority = ThreadPriority.BelowNormal;
break;
case "normal":
MyThreadPriority = ThreadPriority.Normal;
break;
case "abovenormal":
MyThreadPriority = ThreadPriority.AboveNormal;
break;
case "highest":
MyThreadPriority = ThreadPriority.Highest;
break;
default:
MyThreadPriority = ThreadPriority.BelowNormal; // Default
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\".");
break;
}
// Now set that priority
if (EventQueueThread != null)
if (EventQueueThread.IsAlive)
EventQueueThread.Priority = MyThreadPriority;
}
/// <summary>
/// Start thread
/// </summary>
private void Start()
{
EventQueueThread = new Thread(EventQueueThreadLoop);
EventQueueThread.IsBackground = true;
EventQueueThread.Priority = MyThreadPriority;
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
EventQueueThread.Start();
// Look at this... Don't you wish everyone did that solid coding everywhere? :P
if (ThreadCount == int.MaxValue)
ThreadCount = 0;
ThreadCount++;
}
public void Stop()
{
PleaseShutdown = true; // Set shutdown flag
Thread.Sleep(100); // Wait a bit
if (EventQueueThread != null && EventQueueThread.IsAlive == true)
{
try
{
EventQueueThread.Abort(); // Send abort
EventQueueThread.Join(); // Wait for it
}
catch (Exception)
{
//myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Exception killing worker thread: " + e.ToString());
}
}
}
/// <summary>
/// Queue processing thread loop
/// </summary>
private void EventQueueThreadLoop()
{
//myScriptEngine.m_logger.Verbose(ScriptEngineName, "EventQueueManager Worker thread spawned");
try
{
while (true)
{
try
{
EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct();
while (true)
{
// Every now and then check if we should shut down
if (PleaseShutdown || eventQueueManager.ThreadsToExit > 0)
{
// Someone should shut down, lets get exclusive lock
lock (eventQueueManager.ThreadsToExitLock)
{
// Lets re-check in case someone grabbed it
if (eventQueueManager.ThreadsToExit > 0)
{
// Its crowded here so we'll shut down
eventQueueManager.ThreadsToExit--;
Stop();
return;
}
else
{
// We have been asked to shut down
Stop();
return;
}
}
}
//try
// {
EventQueueManager.QueueItemStruct QIS = BlankQIS;
bool GotItem = false;
if (PleaseShutdown)
return;
if (eventQueueManager.eventQueue.Count == 0)
{
// Nothing to do? Sleep a bit waiting for something to do
Thread.Sleep(nothingToDoSleepms);
}
else
{
// Something in queue, process
//myScriptEngine.m_logger.Verbose(ScriptEngineName, "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
lock (eventQueueManager.queueLock)
{
GotItem = false;
for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++)
{
// Get queue item
QIS = eventQueueManager.eventQueue.Dequeue();
// Check if object is being processed by someone else
if (eventQueueManager.TryLock(QIS.localID) == false)
{
// Object is already being processed, requeue it
eventQueueManager.eventQueue.Enqueue(QIS);
}
else
{
// We have lock on an object and can process it
GotItem = true;
break;
}
} // go through queue
} // lock
if (GotItem == true)
{
// Execute function
try
{
#if DEBUG
eventQueueManager.m_ScriptEngine.Log.Debug(ScriptEngineName,
"Executing event:\r\n"
+ "QIS.localID: " + QIS.localID
+ ", QIS.itemID: " + QIS.itemID
+ ", QIS.functionName: " +
QIS.functionName);
#endif
LastExecutionStarted = DateTime.Now.Ticks;
KillCurrentScript = false;
InExecution = true;
eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
QIS.itemID,
QIS.functionName,
QIS.llDetectParams,
QIS.param);
InExecution = false;
}
catch (Exception e)
{
InExecution = false;
// DISPLAY ERROR INWORLD
string text = "Error executing script function \"" + QIS.functionName +
"\":\r\n";
if (e.InnerException != null)
{
// Send inner exception
text += e.InnerException.Message.ToString();
}
else
{
text += "\r\n";
// Send normal
text += e.Message.ToString();
}
if (KillCurrentScript)
text += "\r\nScript will be deactivated!";
try
{
if (text.Length > 1500)
text = text.Substring(0, 1500);
IScriptHost m_host =
eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
//if (m_host != null)
//{
eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
ChatTypeEnum.Say, 0,
m_host.AbsolutePosition,
m_host.Name, m_host.UUID);
}
catch
{
//}
//else
//{
// T oconsole
eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName,
"Unable to send text in-world:\r\n" +
text);
}
finally
{
// So we are done sending message in-world
if (KillCurrentScript)
{
eventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
QIS.localID, QIS.itemID);
}
}
}
finally
{
InExecution = false;
eventQueueManager.ReleaseLock(QIS.localID);
}
}
} // Something in queue
}
}
catch (ThreadAbortException tae)
{
eventQueueManager.m_ScriptEngine.Log.Notice(ScriptEngineName, "ThreadAbortException while executing function.");
}
catch (Exception e)
{
eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, "Exception in EventQueueThreadLoop: " + e.ToString());
}
} // while
} // try
catch (ThreadAbortException)
{
//myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Worker thread killed: " + tae.Message);
}
}
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Environment.Scenes.Scripting;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class
/// </summary>
public class EventQueueThreadClass: iScriptEngineFunctionModule
{
/// <summary>
/// How many ms to sleep if queue is empty
/// </summary>
private int nothingToDoSleepms;// = 50;
private ThreadPriority MyThreadPriority;
public long LastExecutionStarted;
public bool InExecution = false;
public bool KillCurrentScript = false;
private EventQueueManager eventQueueManager;
public Thread EventQueueThread;
private static int ThreadCount = 0;
private string ScriptEngineName = "ScriptEngine.Common";
public EventQueueThreadClass(EventQueueManager eqm)
{
eventQueueManager = eqm;
ReadConfig();
Start();
}
~EventQueueThreadClass()
{
Stop();
}
public void ReadConfig()
{
ScriptEngineName = eventQueueManager.m_ScriptEngine.ScriptEngineName;
nothingToDoSleepms = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
// Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
switch (pri.ToLower())
{
case "lowest":
MyThreadPriority = ThreadPriority.Lowest;
break;
case "belownormal":
MyThreadPriority = ThreadPriority.BelowNormal;
break;
case "normal":
MyThreadPriority = ThreadPriority.Normal;
break;
case "abovenormal":
MyThreadPriority = ThreadPriority.AboveNormal;
break;
case "highest":
MyThreadPriority = ThreadPriority.Highest;
break;
default:
MyThreadPriority = ThreadPriority.BelowNormal; // Default
eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\".");
break;
}
// Now set that priority
if (EventQueueThread != null)
if (EventQueueThread.IsAlive)
EventQueueThread.Priority = MyThreadPriority;
}
/// <summary>
/// Start thread
/// </summary>
private void Start()
{
EventQueueThread = new Thread(EventQueueThreadLoop);
EventQueueThread.IsBackground = true;
EventQueueThread.Priority = MyThreadPriority;
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
EventQueueThread.Start();
// Look at this... Don't you wish everyone did that solid coding everywhere? :P
if (ThreadCount == int.MaxValue)
ThreadCount = 0;
ThreadCount++;
}
public void Stop()
{
PleaseShutdown = true; // Set shutdown flag
Thread.Sleep(100); // Wait a bit
if (EventQueueThread != null && EventQueueThread.IsAlive == true)
{
try
{
EventQueueThread.Abort(); // Send abort
EventQueueThread.Join(); // Wait for it
}
catch (Exception)
{
//myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Exception killing worker thread: " + e.ToString());
}
}
}
/// <summary>
/// Queue processing thread loop
/// </summary>
private void EventQueueThreadLoop()
{
//myScriptEngine.m_logger.Verbose(ScriptEngineName, "EventQueueManager Worker thread spawned");
try
{
while (true)
{
try
{
EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct();
while (true)
{
// Every now and then check if we should shut down
if (PleaseShutdown || eventQueueManager.ThreadsToExit > 0)
{
// Someone should shut down, lets get exclusive lock
lock (eventQueueManager.ThreadsToExitLock)
{
// Lets re-check in case someone grabbed it
if (eventQueueManager.ThreadsToExit > 0)
{
// Its crowded here so we'll shut down
eventQueueManager.ThreadsToExit--;
Stop();
return;
}
else
{
// We have been asked to shut down
Stop();
return;
}
}
}
//try
// {
EventQueueManager.QueueItemStruct QIS = BlankQIS;
bool GotItem = false;
if (PleaseShutdown)
return;
if (eventQueueManager.eventQueue.Count == 0)
{
// Nothing to do? Sleep a bit waiting for something to do
Thread.Sleep(nothingToDoSleepms);
}
else
{
// Something in queue, process
//myScriptEngine.m_logger.Verbose(ScriptEngineName, "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
lock (eventQueueManager.queueLock)
{
GotItem = false;
for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++)
{
// Get queue item
QIS = eventQueueManager.eventQueue.Dequeue();
// Check if object is being processed by someone else
if (eventQueueManager.TryLock(QIS.localID) == false)
{
// Object is already being processed, requeue it
eventQueueManager.eventQueue.Enqueue(QIS);
}
else
{
// We have lock on an object and can process it
GotItem = true;
break;
}
} // go through queue
} // lock
if (GotItem == true)
{
// Execute function
try
{
#if DEBUG
eventQueueManager.m_ScriptEngine.Log.Debug(ScriptEngineName,
"Executing event:\r\n"
+ "QIS.localID: " + QIS.localID
+ ", QIS.itemID: " + QIS.itemID
+ ", QIS.functionName: " +
QIS.functionName);
#endif
LastExecutionStarted = DateTime.Now.Ticks;
KillCurrentScript = false;
InExecution = true;
eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
QIS.itemID,
QIS.functionName,
QIS.llDetectParams,
QIS.param);
InExecution = false;
}
catch (Exception e)
{
InExecution = false;
// DISPLAY ERROR INWORLD
string text = "Error executing script function \"" + QIS.functionName +
"\":\r\n";
if (e.InnerException != null)
{
// Send inner exception
text += e.InnerException.Message.ToString();
}
else
{
text += "\r\n";
// Send normal
text += e.Message.ToString();
}
if (KillCurrentScript)
text += "\r\nScript will be deactivated!";
try
{
if (text.Length > 1500)
text = text.Substring(0, 1500);
IScriptHost m_host =
eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
//if (m_host != null)
//{
eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
ChatTypeEnum.Say, 0,
m_host.AbsolutePosition,
m_host.Name, m_host.UUID);
}
catch
{
//}
//else
//{
// T oconsole
eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName,
"Unable to send text in-world:\r\n" +
text);
}
finally
{
// So we are done sending message in-world
if (KillCurrentScript)
{
eventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
QIS.localID, QIS.itemID);
}
}
}
finally
{
InExecution = false;
eventQueueManager.ReleaseLock(QIS.localID);
}
}
} // Something in queue
}
}
catch (ThreadAbortException tae)
{
eventQueueManager.m_ScriptEngine.Log.Notice(ScriptEngineName, "ThreadAbortException while executing function.");
}
catch (Exception e)
{
eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, "Exception in EventQueueThreadLoop: " + e.ToString());
}
} // while
} // try
catch (ThreadAbortException)
{
//myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Worker thread killed: " + tae.Message);
}
}
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}

View File

@ -1,163 +1,163 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// This class does maintenance on script engine.
/// </summary>
public class MaintenanceThread : iScriptEngineFunctionModule
{
public ScriptEngine m_ScriptEngine;
private int MaintenanceLoopms;
public MaintenanceThread(ScriptEngine _ScriptEngine)
{
m_ScriptEngine = _ScriptEngine;
ReadConfig();
// Start maintenance thread
StartMaintenanceThread();
}
~MaintenanceThread()
{
StopMaintenanceThread();
}
public void ReadConfig()
{
MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50);
}
#region " Maintenance thread "
/// <summary>
/// Maintenance thread. Enforcing max execution time for example.
/// </summary>
public Thread MaintenanceThreadThread;
/// <summary>
/// Starts maintenance thread
/// </summary>
private void StartMaintenanceThread()
{
if (MaintenanceThreadThread == null)
{
MaintenanceThreadThread = new Thread(MaintenanceLoop);
MaintenanceThreadThread.Name = "ScriptMaintenanceThread";
MaintenanceThreadThread.IsBackground = true;
MaintenanceThreadThread.Start();
}
}
/// <summary>
/// Stops maintenance thread
/// </summary>
private void StopMaintenanceThread()
{
#if DEBUG
m_ScriptEngine.Log.Debug(m_ScriptEngine.ScriptEngineName, "StopMaintenanceThread() called");
#endif
PleaseShutdown = true;
Thread.Sleep(100);
try
{
if (MaintenanceThreadThread != null)
{
if (MaintenanceThreadThread.IsAlive)
{
MaintenanceThreadThread.Abort();
}
}
}
catch (Exception ex)
{
m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception stopping maintenence thread: " + ex.ToString());
}
}
/// <summary>
/// A thread should run in this loop and check all running scripts
/// </summary>
public void MaintenanceLoop()
{
if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms)
m_ScriptEngine.Log.Warn(m_ScriptEngine.ScriptEngineName,
"Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run.");
while (true)
{
try
{
long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks;
long Last_ReReadConfigFilens = DateTime.Now.Ticks;
while (true)
{
System.Threading.Thread.Sleep(MaintenanceLoopms); // Sleep before next pass
if (PleaseShutdown)
return;
if (m_ScriptEngine != null)
{
//
// Re-reading config every x seconds
//
if (m_ScriptEngine.RefreshConfigFileSeconds > 0)
{
// Check if its time to re-read config
if (DateTime.Now.Ticks - Last_ReReadConfigFilens > m_ScriptEngine.RefreshConfigFilens)
{
// Its time to re-read config file
m_ScriptEngine.ReadConfig();
Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time
}
}
//
// Adjust number of running script threads if not correct
//
if (m_ScriptEngine.m_EventQueueManager != null)
m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads();
//
// Check if any script has exceeded its max execution time
//
if (m_ScriptEngine.m_EventQueueManager != null && m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime)
{
// We are enforcing execution time
if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens)
{
// Its time to check again
m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check
Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time
}
}
} // m_ScriptEngine != null
}
}
catch (Exception ex)
{
m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString());
Thread.Sleep(5000);
}
}
}
#endregion
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
/// <summary>
/// This class does maintenance on script engine.
/// </summary>
public class MaintenanceThread : iScriptEngineFunctionModule
{
public ScriptEngine m_ScriptEngine;
private int MaintenanceLoopms;
public MaintenanceThread(ScriptEngine _ScriptEngine)
{
m_ScriptEngine = _ScriptEngine;
ReadConfig();
// Start maintenance thread
StartMaintenanceThread();
}
~MaintenanceThread()
{
StopMaintenanceThread();
}
public void ReadConfig()
{
MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50);
}
#region " Maintenance thread "
/// <summary>
/// Maintenance thread. Enforcing max execution time for example.
/// </summary>
public Thread MaintenanceThreadThread;
/// <summary>
/// Starts maintenance thread
/// </summary>
private void StartMaintenanceThread()
{
if (MaintenanceThreadThread == null)
{
MaintenanceThreadThread = new Thread(MaintenanceLoop);
MaintenanceThreadThread.Name = "ScriptMaintenanceThread";
MaintenanceThreadThread.IsBackground = true;
MaintenanceThreadThread.Start();
}
}
/// <summary>
/// Stops maintenance thread
/// </summary>
private void StopMaintenanceThread()
{
#if DEBUG
m_ScriptEngine.Log.Debug(m_ScriptEngine.ScriptEngineName, "StopMaintenanceThread() called");
#endif
PleaseShutdown = true;
Thread.Sleep(100);
try
{
if (MaintenanceThreadThread != null)
{
if (MaintenanceThreadThread.IsAlive)
{
MaintenanceThreadThread.Abort();
}
}
}
catch (Exception ex)
{
m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception stopping maintenence thread: " + ex.ToString());
}
}
/// <summary>
/// A thread should run in this loop and check all running scripts
/// </summary>
public void MaintenanceLoop()
{
if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms)
m_ScriptEngine.Log.Warn(m_ScriptEngine.ScriptEngineName,
"Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run.");
while (true)
{
try
{
long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks;
long Last_ReReadConfigFilens = DateTime.Now.Ticks;
while (true)
{
System.Threading.Thread.Sleep(MaintenanceLoopms); // Sleep before next pass
if (PleaseShutdown)
return;
if (m_ScriptEngine != null)
{
//
// Re-reading config every x seconds
//
if (m_ScriptEngine.RefreshConfigFileSeconds > 0)
{
// Check if its time to re-read config
if (DateTime.Now.Ticks - Last_ReReadConfigFilens > m_ScriptEngine.RefreshConfigFilens)
{
// Its time to re-read config file
m_ScriptEngine.ReadConfig();
Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time
}
}
//
// Adjust number of running script threads if not correct
//
if (m_ScriptEngine.m_EventQueueManager != null)
m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads();
//
// Check if any script has exceeded its max execution time
//
if (m_ScriptEngine.m_EventQueueManager != null && m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime)
{
// We are enforcing execution time
if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens)
{
// Its time to check again
m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check
Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time
}
}
} // m_ScriptEngine != null
}
}
catch (Exception ex)
{
m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString());
Thread.Sleep(5000);
}
}
}
#endregion
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}

View File

@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
public interface iScriptEngineFunctionModule
{
void ReadConfig();
bool PleaseShutdown { get; set; }
}
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{
public interface iScriptEngineFunctionModule
{
void ReadConfig();
bool PleaseShutdown { get; set; }
}
}

View File

@ -1,63 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{595D67F3-B413-4A43-8568-5B5930E3B31D}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenSim._32BitLaunch</RootNamespace>
<AssemblyName>OpenSim.32BitLaunch</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Region\Application\OpenSim.csproj">
<Project>{AC9EB8AB-0000-0000-0000-000000000000}</Project>
<Name>OpenSim</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{595D67F3-B413-4A43-8568-5B5930E3B31D}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OpenSim._32BitLaunch</RootNamespace>
<AssemblyName>OpenSim.32BitLaunch</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Region\Application\OpenSim.csproj">
<Project>{AC9EB8AB-0000-0000-0000-000000000000}</Project>
<Name>OpenSim</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,10 +1,10 @@
namespace OpenSim._32BitLaunch
{
class Program
{
static void Main(string[] args)
{
OpenSim.Application.Main(args);
}
}
}
namespace OpenSim._32BitLaunch
{
class Program
{
static void Main(string[] args)
{
OpenSim.Application.Main(args);
}
}
}

View File

@ -1,36 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.32BitLaunch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("OpenSim.32BitLaunch")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5072e919-46ab-47e6-8a63-08108324ccdf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.32BitLaunch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("OpenSim.32BitLaunch")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5072e919-46ab-47e6-8a63-08108324ccdf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

0
bin/OpenSim.32BitLaunch.exe Normal file → Executable file
View File

0
bin/OpenSim.32BitLaunch.vshost.exe Normal file → Executable file
View File

View File

@ -60,6 +60,7 @@ property_map = {
".mdp" : textfile,
".mds" : textfile,
".nsi" : textfile,
".pdb" : binary,
".php" : script,
".pidb" : binary,
".pl" : script,