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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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