aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
diff options
context:
space:
mode:
authorMelanie2012-06-06 13:07:05 +0100
committerMelanie2012-06-06 13:07:05 +0100
commite733fb32cf76672cfddc25b3c9c02c50c025e2db (patch)
tree1535c9e7d70cdb5f2e0779db8fc85fb98ede7ca5 /OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
parentMerge branch 'master' into careminster (diff)
parentminor: Change log messages on Warp3DImageModule to show they are from this mo... (diff)
downloadopensim-SC_OLD-e733fb32cf76672cfddc25b3c9c02c50c025e2db.zip
opensim-SC_OLD-e733fb32cf76672cfddc25b3c9c02c50c025e2db.tar.gz
opensim-SC_OLD-e733fb32cf76672cfddc25b3c9c02c50c025e2db.tar.bz2
opensim-SC_OLD-e733fb32cf76672cfddc25b3c9c02c50c025e2db.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SimStatsReporter.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs214
1 files changed, 115 insertions, 99 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 0efe4c4..18e6ece 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -56,10 +56,17 @@ namespace OpenSim.Region.Framework.Scenes
56 56
57 public event YourStatsAreWrong OnStatsIncorrect; 57 public event YourStatsAreWrong OnStatsIncorrect;
58 58
59 private SendStatResult handlerSendStatResult = null; 59 private SendStatResult handlerSendStatResult;
60 60
61 private YourStatsAreWrong handlerStatsIncorrect = null; 61 private YourStatsAreWrong handlerStatsIncorrect;
62 62
63 /// <summary>
64 /// These are the IDs of stats sent in the StatsPacket to the viewer.
65 /// </summary>
66 /// <remarks>
67 /// Some of these are not relevant to OpenSimulator since it is architected differently to other simulators
68 /// (e.g. script instructions aren't executed as part of the frame loop so 'script time' is tricky).
69 /// </remarks>
63 public enum Stats : uint 70 public enum Stats : uint
64 { 71 {
65 TimeDilation = 0, 72 TimeDilation = 0,
@@ -83,20 +90,20 @@ namespace OpenSim.Region.Framework.Scenes
83 OutPacketsPerSecond = 18, 90 OutPacketsPerSecond = 18,
84 PendingDownloads = 19, 91 PendingDownloads = 19,
85 PendingUploads = 20, 92 PendingUploads = 20,
86 VirtualSizeKB = 21, 93 VirtualSizeKb = 21,
87 ResidentSizeKB = 22, 94 ResidentSizeKb = 22,
88 PendingLocalUploads = 23, 95 PendingLocalUploads = 23,
89 UnAckedBytes = 24, 96 UnAckedBytes = 24,
90 PhysicsPinnedTasks = 25, 97 PhysicsPinnedTasks = 25,
91 PhysicsLODTasks = 26, 98 PhysicsLodTasks = 26,
92 PhysicsStepMS = 27, 99 SimPhysicsStepMs = 27,
93 PhysicsShapeMS = 28, 100 SimPhysicsShapeMs = 28,
94 PhysicsOtherMS = 29, 101 SimPhysicsOtherMs = 29,
95 PhysicsMemory = 30, 102 SimPhysicsMemory = 30,
96 ScriptEPS = 31, 103 ScriptEps = 31,
97 SimSpareTime = 32, 104 SimSpareMs = 32,
98 SimSleepTime = 33, 105 SimSleepMs = 33,
99 IOPumpTime = 34 106 SimIoPumpTime = 34
100 } 107 }
101 108
102 /// <summary> 109 /// <summary>
@@ -130,10 +137,15 @@ namespace OpenSim.Region.Framework.Scenes
130 private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>(); 137 private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>();
131 138
132 // Sending a stats update every 3 seconds- 139 // Sending a stats update every 3 seconds-
133 private int statsUpdatesEveryMS = 3000; 140 private int m_statsUpdatesEveryMS = 3000;
134 private float statsUpdateFactor = 0; 141 private float m_statsUpdateFactor;
135 private float m_timeDilation = 0; 142 private float m_timeDilation;
136 private int m_fps = 0; 143 private int m_fps;
144
145 /// <summary>
146 /// Number of the last frame on which we processed a stats udpate.
147 /// </summary>
148 private uint m_lastUpdateFrame;
137 149
138 /// <summary> 150 /// <summary>
139 /// Our nominal fps target, as expected in fps stats when a sim is running normally. 151 /// Our nominal fps target, as expected in fps stats when a sim is running normally.
@@ -151,43 +163,42 @@ namespace OpenSim.Region.Framework.Scenes
151 private float m_reportedFpsCorrectionFactor = 5; 163 private float m_reportedFpsCorrectionFactor = 5;
152 164
153 // saved last reported value so there is something available for llGetRegionFPS 165 // saved last reported value so there is something available for llGetRegionFPS
154 private float lastReportedSimFPS = 0; 166 private float lastReportedSimFPS;
155 private float[] lastReportedSimStats = new float[23]; 167 private float[] lastReportedSimStats = new float[22];
156 private float m_pfps = 0; 168 private float m_pfps;
157 169
158 /// <summary> 170 /// <summary>
159 /// Number of agent updates requested in this stats cycle 171 /// Number of agent updates requested in this stats cycle
160 /// </summary> 172 /// </summary>
161 private int m_agentUpdates = 0; 173 private int m_agentUpdates;
162 174
163 /// <summary> 175 /// <summary>
164 /// Number of object updates requested in this stats cycle 176 /// Number of object updates requested in this stats cycle
165 /// </summary> 177 /// </summary>
166 private int m_objectUpdates; 178 private int m_objectUpdates;
167 179
168 private int m_frameMS = 0; 180 private int m_frameMS;
169 private int m_netMS = 0; 181 private int m_spareMS;
170 private int m_agentMS = 0; 182 private int m_netMS;
171 private int m_physicsMS = 0; 183 private int m_agentMS;
172 private int m_imageMS = 0; 184 private int m_physicsMS;
173 private int m_otherMS = 0; 185 private int m_imageMS;
174 private int m_sleeptimeMS = 0; 186 private int m_otherMS;
175
176 187
177//Ckrinke: (3-21-08) Comment out to remove a compiler warning. Bring back into play when needed. 188//Ckrinke: (3-21-08) Comment out to remove a compiler warning. Bring back into play when needed.
178//Ckrinke private int m_scriptMS = 0; 189//Ckrinke private int m_scriptMS = 0;
179 190
180 private int m_rootAgents = 0; 191 private int m_rootAgents;
181 private int m_childAgents = 0; 192 private int m_childAgents;
182 private int m_numPrim = 0; 193 private int m_numPrim;
183 private int m_inPacketsPerSecond = 0; 194 private int m_inPacketsPerSecond;
184 private int m_outPacketsPerSecond = 0; 195 private int m_outPacketsPerSecond;
185 private int m_activePrim = 0; 196 private int m_activePrim;
186 private int m_unAckedBytes = 0; 197 private int m_unAckedBytes;
187 private int m_pendingDownloads = 0; 198 private int m_pendingDownloads;
188 private int m_pendingUploads = 0; 199 private int m_pendingUploads = 0; // FIXME: Not currently filled in
189 private int m_activeScripts = 0; 200 private int m_activeScripts;
190 private int m_scriptLinesPerSecond = 0; 201 private int m_scriptLinesPerSecond;
191 202
192 private int m_objectCapacity = 45000; 203 private int m_objectCapacity = 45000;
193 204
@@ -203,13 +214,13 @@ namespace OpenSim.Region.Framework.Scenes
203 { 214 {
204 m_scene = scene; 215 m_scene = scene;
205 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; 216 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps;
206 statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); 217 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
207 ReportingRegion = scene.RegionInfo; 218 ReportingRegion = scene.RegionInfo;
208 219
209 m_objectCapacity = scene.RegionInfo.ObjectCapacity; 220 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
210 m_report.AutoReset = true; 221 m_report.AutoReset = true;
211 m_report.Interval = statsUpdatesEveryMS; 222 m_report.Interval = m_statsUpdatesEveryMS;
212 m_report.Elapsed += statsHeartBeat; 223 m_report.Elapsed += TriggerStatsHeartbeat;
213 m_report.Enabled = true; 224 m_report.Enabled = true;
214 225
215 if (StatsManager.SimExtraStats != null) 226 if (StatsManager.SimExtraStats != null)
@@ -218,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes
218 229
219 public void Close() 230 public void Close()
220 { 231 {
221 m_report.Elapsed -= statsHeartBeat; 232 m_report.Elapsed -= TriggerStatsHeartbeat;
222 m_report.Close(); 233 m_report.Close();
223 } 234 }
224 235
@@ -228,14 +239,28 @@ namespace OpenSim.Region.Framework.Scenes
228 /// <param name='ms'></param> 239 /// <param name='ms'></param>
229 public void SetUpdateMS(int ms) 240 public void SetUpdateMS(int ms)
230 { 241 {
231 statsUpdatesEveryMS = ms; 242 m_statsUpdatesEveryMS = ms;
232 statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); 243 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
233 m_report.Interval = statsUpdatesEveryMS; 244 m_report.Interval = m_statsUpdatesEveryMS;
245 }
246
247 private void TriggerStatsHeartbeat(object sender, EventArgs args)
248 {
249 try
250 {
251 statsHeartBeat(sender, args);
252 }
253 catch (Exception e)
254 {
255 m_log.Warn(string.Format(
256 "[SIM STATS REPORTER] Update for {0} failed with exception ",
257 m_scene.RegionInfo.RegionName), e);
258 }
234 } 259 }
235 260
236 private void statsHeartBeat(object sender, EventArgs e) 261 private void statsHeartBeat(object sender, EventArgs e)
237 { 262 {
238 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[23]; 263 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22];
239 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); 264 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
240 265
241 // Know what's not thread safe in Mono... modifying timers. 266 // Know what's not thread safe in Mono... modifying timers.
@@ -262,7 +287,7 @@ namespace OpenSim.Region.Framework.Scenes
262 int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); 287 int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor);
263 288
264 // save the reported value so there is something available for llGetRegionFPS 289 // save the reported value so there is something available for llGetRegionFPS
265 lastReportedSimFPS = reportedFPS / statsUpdateFactor; 290 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
266 291
267 float physfps = ((m_pfps / 1000)); 292 float physfps = ((m_pfps / 1000));
268 293
@@ -273,7 +298,6 @@ namespace OpenSim.Region.Framework.Scenes
273 physfps = 0; 298 physfps = 0;
274 299
275#endregion 300#endregion
276 float factor = 1 / statsUpdateFactor;
277 if (reportedFPS <= 0) 301 if (reportedFPS <= 0)
278 reportedFPS = 1; 302 reportedFPS = 1;
279 303
@@ -284,21 +308,9 @@ namespace OpenSim.Region.Framework.Scenes
284 float targetframetime = 1100.0f / (float)m_nominalReportedFps; 308 float targetframetime = 1100.0f / (float)m_nominalReportedFps;
285 309
286 float sparetime; 310 float sparetime;
287 float sleeptime;
288 if (TotalFrameTime > targetframetime) 311 if (TotalFrameTime > targetframetime)
289 { 312 {
290 sparetime = 0; 313 sparetime = 0;
291 sleeptime = 0;
292 }
293 else
294 {
295 sparetime = m_frameMS - m_physicsMS - m_agentMS;
296 sparetime *= perframe;
297 if (sparetime < 0)
298 sparetime = 0;
299 else if (sparetime > TotalFrameTime)
300 sparetime = TotalFrameTime;
301 sleeptime = m_sleeptimeMS * perframe;
302 } 314 }
303 315
304 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount(); 316 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
@@ -315,11 +327,19 @@ namespace OpenSim.Region.Framework.Scenes
315 // m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS; 327 // m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS;
316 // m_imageMS m_netMS are not included in m_frameMS 328 // m_imageMS m_netMS are not included in m_frameMS
317 329
318 m_otherMS = m_frameMS - m_physicsMS - m_agentMS - m_sleeptimeMS; 330 m_otherMS = m_frameMS - m_physicsMS - m_agentMS;
319 if (m_otherMS < 0) 331 if (m_otherMS < 0)
320 m_otherMS = 0; 332 m_otherMS = 0;
321 333
322 for (int i = 0; i < 23; i++) 334 uint thisFrame = m_scene.Frame;
335 float framesUpdated = (float)(thisFrame - m_lastUpdateFrame) * m_reportedFpsCorrectionFactor;
336 m_lastUpdateFrame = thisFrame;
337
338 // Avoid div-by-zero if somehow we've not updated any frames.
339 if (framesUpdated == 0)
340 framesUpdated = 1;
341
342 for (int i = 0; i < 22; i++)
323 { 343 {
324 sb[i] = new SimStatsPacket.StatBlock(); 344 sb[i] = new SimStatsPacket.StatBlock();
325 } 345 }
@@ -328,13 +348,13 @@ namespace OpenSim.Region.Framework.Scenes
328 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 348 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
329 349
330 sb[1].StatID = (uint) Stats.SimFPS; 350 sb[1].StatID = (uint) Stats.SimFPS;
331 sb[1].StatValue = reportedFPS / statsUpdateFactor; 351 sb[1].StatValue = reportedFPS / m_statsUpdateFactor;
332 352
333 sb[2].StatID = (uint) Stats.PhysicsFPS; 353 sb[2].StatID = (uint) Stats.PhysicsFPS;
334 sb[2].StatValue = physfps / statsUpdateFactor; 354 sb[2].StatValue = physfps / m_statsUpdateFactor;
335 355
336 sb[3].StatID = (uint) Stats.AgentUpdates; 356 sb[3].StatID = (uint) Stats.AgentUpdates;
337 sb[3].StatValue = (m_agentUpdates / statsUpdateFactor); 357 sb[3].StatValue = (m_agentUpdates / m_statsUpdateFactor);
338 358
339 sb[4].StatID = (uint) Stats.Agents; 359 sb[4].StatID = (uint) Stats.Agents;
340 sb[4].StatValue = m_rootAgents; 360 sb[4].StatValue = m_rootAgents;
@@ -349,38 +369,31 @@ namespace OpenSim.Region.Framework.Scenes
349 sb[7].StatValue = m_activePrim; 369 sb[7].StatValue = m_activePrim;
350 370
351 sb[8].StatID = (uint)Stats.FrameMS; 371 sb[8].StatID = (uint)Stats.FrameMS;
352 // sb[8].StatValue = m_frameMS / statsUpdateFactor; 372 sb[8].StatValue = m_frameMS / framesUpdated;
353 sb[8].StatValue = TotalFrameTime;
354 373
355 sb[9].StatID = (uint)Stats.NetMS; 374 sb[9].StatID = (uint)Stats.NetMS;
356 // sb[9].StatValue = m_netMS / statsUpdateFactor; 375 sb[9].StatValue = m_netMS / framesUpdated;
357 sb[9].StatValue = m_netMS * perframe;
358 376
359 sb[10].StatID = (uint)Stats.PhysicsMS; 377 sb[10].StatID = (uint)Stats.PhysicsMS;
360 // sb[10].StatValue = m_physicsMS / statsUpdateFactor; 378 sb[10].StatValue = m_physicsMS / framesUpdated;
361 sb[10].StatValue = m_physicsMS * perframe;
362 379
363 sb[11].StatID = (uint)Stats.ImageMS ; 380 sb[11].StatID = (uint)Stats.ImageMS ;
364 // sb[11].StatValue = m_imageMS / statsUpdateFactor; 381 sb[11].StatValue = m_imageMS / framesUpdated;
365 sb[11].StatValue = m_imageMS * perframe;
366 382
367 sb[12].StatID = (uint)Stats.OtherMS; 383 sb[12].StatID = (uint)Stats.OtherMS;
368 // sb[12].StatValue = m_otherMS / statsUpdateFactor; 384 sb[12].StatValue = m_otherMS / framesUpdated;
369 sb[12].StatValue = m_otherMS * perframe;
370
371 385
372 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 386 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
373 sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); 387 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor);
374 388
375 sb[14].StatID = (uint)Stats.OutPacketsPerSecond; 389 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
376 sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor); 390 sb[14].StatValue = (m_outPacketsPerSecond / m_statsUpdateFactor);
377 391
378 sb[15].StatID = (uint)Stats.UnAckedBytes; 392 sb[15].StatID = (uint)Stats.UnAckedBytes;
379 sb[15].StatValue = m_unAckedBytes; 393 sb[15].StatValue = m_unAckedBytes;
380 394
381 sb[16].StatID = (uint)Stats.AgentMS; 395 sb[16].StatID = (uint)Stats.AgentMS;
382// sb[16].StatValue = m_agentMS / statsUpdateFactor; 396 sb[16].StatValue = m_agentMS / framesUpdated;
383 sb[16].StatValue = m_agentMS * perframe;
384 397
385 sb[17].StatID = (uint)Stats.PendingDownloads; 398 sb[17].StatID = (uint)Stats.PendingDownloads;
386 sb[17].StatValue = m_pendingDownloads; 399 sb[17].StatValue = m_pendingDownloads;
@@ -392,15 +405,12 @@ namespace OpenSim.Region.Framework.Scenes
392 sb[19].StatValue = m_activeScripts; 405 sb[19].StatValue = m_activeScripts;
393 406
394 sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; 407 sb[20].StatID = (uint)Stats.ScriptLinesPerSecond;
395 sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor; 408 sb[20].StatValue = m_scriptLinesPerSecond / m_statsUpdateFactor;
396 409
397 sb[21].StatID = (uint)Stats.SimSpareTime; 410 sb[21].StatID = (uint)Stats.SimSpareMs;
398 sb[21].StatValue = sparetime; 411 sb[21].StatValue = m_spareMS / framesUpdated;
399 412
400 sb[22].StatID = (uint)Stats.SimSleepTime; 413 for (int i = 0; i < 22; i++)
401 sb[22].StatValue = sleeptime;
402
403 for (int i = 0; i < 23; i++)
404 { 414 {
405 lastReportedSimStats[i] = sb[i].StatValue; 415 lastReportedSimStats[i] = sb[i].StatValue;
406 } 416 }
@@ -419,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
419 // Extra statistics that aren't currently sent to clients 429 // Extra statistics that aren't currently sent to clients
420 lock (m_lastReportedExtraSimStats) 430 lock (m_lastReportedExtraSimStats)
421 { 431 {
422 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / statsUpdateFactor; 432 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
423 433
424 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); 434 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
425 435
@@ -427,16 +437,22 @@ namespace OpenSim.Region.Framework.Scenes
427 { 437 {
428 foreach (KeyValuePair<string, float> tuple in physicsStats) 438 foreach (KeyValuePair<string, float> tuple in physicsStats)
429 { 439 {
430 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / statsUpdateFactor; 440 // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second
441 // Need to change things so that stats source can indicate whether they are per second or
442 // per frame.
443 if (tuple.Key.EndsWith("MS"))
444 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / framesUpdated;
445 else
446 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor;
431 } 447 }
432 } 448 }
433 } 449 }
434 450
435 resetvalues(); 451 ResetValues();
436 } 452 }
437 } 453 }
438 454
439 private void resetvalues() 455 private void ResetValues()
440 { 456 {
441 m_timeDilation = 0; 457 m_timeDilation = 0;
442 m_fps = 0; 458 m_fps = 0;
@@ -454,7 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
454 m_physicsMS = 0; 470 m_physicsMS = 0;
455 m_imageMS = 0; 471 m_imageMS = 0;
456 m_otherMS = 0; 472 m_otherMS = 0;
457 m_sleeptimeMS = 0; 473 m_spareMS = 0;
458 474
459//Ckrinke This variable is not used, so comment to remove compiler warning until it is used. 475//Ckrinke This variable is not used, so comment to remove compiler warning until it is used.
460//Ckrinke m_scriptMS = 0; 476//Ckrinke m_scriptMS = 0;
@@ -533,6 +549,11 @@ namespace OpenSim.Region.Framework.Scenes
533 m_frameMS += ms; 549 m_frameMS += ms;
534 } 550 }
535 551
552 public void AddSpareMS(int ms)
553 {
554 m_spareMS += ms;
555 }
556
536 public void addNetMS(int ms) 557 public void addNetMS(int ms)
537 { 558 {
538 m_netMS += ms; 559 m_netMS += ms;
@@ -558,11 +579,6 @@ namespace OpenSim.Region.Framework.Scenes
558 m_otherMS += ms; 579 m_otherMS += ms;
559 } 580 }
560 581
561 public void addSleepMS(int ms)
562 {
563 m_sleeptimeMS += ms;
564 }
565
566 public void AddPendingDownloads(int count) 582 public void AddPendingDownloads(int count)
567 { 583 {
568 m_pendingDownloads += count; 584 m_pendingDownloads += count;