diff options
author | Tedd Hansen | 2007-08-25 19:08:15 +0000 |
---|---|---|
committer | Tedd Hansen | 2007-08-25 19:08:15 +0000 |
commit | b75c1b2191640f4a140dc4cd0e8ce35ab64863d9 (patch) | |
tree | 05a5194e8e304df86897003bdbceca68fd65fd80 /OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs | |
parent | Scripts no longer crash sim after 5 minutes (override InitializeLifetimeServi... (diff) | |
download | opensim-SC-b75c1b2191640f4a140dc4cd0e8ce35ab64863d9.zip opensim-SC-b75c1b2191640f4a140dc4cd0e8ce35ab64863d9.tar.gz opensim-SC-b75c1b2191640f4a140dc4cd0e8ce35ab64863d9.tar.bz2 opensim-SC-b75c1b2191640f4a140dc4cd0e8ce35ab64863d9.tar.xz |
Added class for "long commands" (command that returns as event) with dedicated thread for processing. Added support for llSetTimerEvent(). Deleting old compiled scripts before new compile is attempted (avoids loading wrong script on compile error).
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs new file mode 100644 index 0000000..e2c039c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs | |||
@@ -0,0 +1,145 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Threading; | ||
5 | using libsecondlife; | ||
6 | |||
7 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | ||
8 | { | ||
9 | /// <summary> | ||
10 | /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. | ||
11 | /// </summary> | ||
12 | class LSLLongCmdHandler | ||
13 | { | ||
14 | private Thread CmdHandlerThread; | ||
15 | private int CmdHandlerThreadCycleSleepms = 100; | ||
16 | |||
17 | private ScriptEngine myScriptEngine; | ||
18 | public LSLLongCmdHandler(ScriptEngine _ScriptEngine) | ||
19 | { | ||
20 | myScriptEngine = _ScriptEngine; | ||
21 | |||
22 | // Start the thread that will be doing the work | ||
23 | CmdHandlerThread = new Thread(CmdHandlerThreadLoop); | ||
24 | CmdHandlerThread.Name = "CmdHandlerThread"; | ||
25 | CmdHandlerThread.Priority = ThreadPriority.BelowNormal; | ||
26 | CmdHandlerThread.IsBackground = true; | ||
27 | CmdHandlerThread.Start(); | ||
28 | } | ||
29 | ~LSLLongCmdHandler() | ||
30 | { | ||
31 | // Shut down thread | ||
32 | try | ||
33 | { | ||
34 | if (CmdHandlerThread != null) | ||
35 | { | ||
36 | if (CmdHandlerThread.IsAlive == true) | ||
37 | { | ||
38 | CmdHandlerThread.Abort(); | ||
39 | CmdHandlerThread.Join(); | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | catch { } | ||
44 | } | ||
45 | |||
46 | private void CmdHandlerThreadLoop() | ||
47 | { | ||
48 | while (true) | ||
49 | { | ||
50 | // Check timers | ||
51 | CheckTimerEvents(); | ||
52 | |||
53 | // Sleep before next cycle | ||
54 | Thread.Sleep(CmdHandlerThreadCycleSleepms); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | /// <summary> | ||
59 | /// Remove a specific script (and all its pending commands) | ||
60 | /// </summary> | ||
61 | /// <param name="m_localID"></param> | ||
62 | /// <param name="m_itemID"></param> | ||
63 | public void RemoveScript(uint m_localID, LLUUID m_itemID) | ||
64 | { | ||
65 | // Remove a specific script | ||
66 | |||
67 | // Remove from: Timers | ||
68 | UnSetTimerEvents(m_localID, m_itemID); | ||
69 | } | ||
70 | |||
71 | |||
72 | // | ||
73 | // TIMER | ||
74 | // | ||
75 | private class TimerClass | ||
76 | { | ||
77 | public uint localID; | ||
78 | public LLUUID itemID; | ||
79 | public double interval; | ||
80 | public DateTime next; | ||
81 | } | ||
82 | private List<TimerClass> Timers = new List<TimerClass>(); | ||
83 | private object ListLock = new object(); | ||
84 | public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) | ||
85 | { | ||
86 | Console.WriteLine("SetTimerEvent"); | ||
87 | |||
88 | // Always remove first, in case this is a re-set | ||
89 | UnSetTimerEvents(m_localID, m_itemID); | ||
90 | if (sec == 0) // Disabling timer | ||
91 | return; | ||
92 | |||
93 | // Add to timer | ||
94 | TimerClass ts = new TimerClass(); | ||
95 | ts.localID = m_localID; | ||
96 | ts.itemID = m_itemID; | ||
97 | ts.interval = sec; | ||
98 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | ||
99 | lock (ListLock) | ||
100 | { | ||
101 | Timers.Add(ts); | ||
102 | } | ||
103 | } | ||
104 | public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) | ||
105 | { | ||
106 | // Remove from timer | ||
107 | lock (ListLock) | ||
108 | { | ||
109 | List<TimerClass> NewTimers = new List<TimerClass>(); | ||
110 | foreach (TimerClass ts in Timers) | ||
111 | { | ||
112 | if (ts.localID != m_localID && ts.itemID != m_itemID) | ||
113 | { | ||
114 | NewTimers.Add(ts); | ||
115 | } | ||
116 | } | ||
117 | Timers.Clear(); | ||
118 | Timers = NewTimers; | ||
119 | } | ||
120 | } | ||
121 | public void CheckTimerEvents() | ||
122 | { | ||
123 | // Nothing to do here? | ||
124 | if (Timers.Count == 0) | ||
125 | return; | ||
126 | |||
127 | // Go through all timers | ||
128 | foreach (TimerClass ts in Timers) | ||
129 | { | ||
130 | // Time has passed? | ||
131 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) | ||
132 | { | ||
133 | // Add it to queue | ||
134 | //Console.WriteLine("Enqueue timer event: " + ts.next.ToUniversalTime().ToString("HH:mm:ss") + " > " + DateTime.Now.ToUniversalTime().ToString("HH:mm:ss")); | ||
135 | myScriptEngine.myEventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", new object[] { }); | ||
136 | // set next interval | ||
137 | |||
138 | |||
139 | ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | } | ||
145 | } | ||