aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs32
-rw-r--r--OpenSim/Region/Environment/Interfaces/ITextureSender.cs61
-rw-r--r--OpenSim/Region/Environment/Modules/TextureDownloadModule.cs22
-rw-r--r--OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs75
-rw-r--r--OpenSim/Region/Environment/Modules/TextureSender.cs33
-rw-r--r--OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs35
6 files changed, 203 insertions, 55 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index e3a4eb8..d04708d 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -242,6 +242,10 @@ namespace OpenSim.Framework.Communications.Cache
242 /// If the asset was not found this is still called with the asset UUID but with a null asset data reference</param> 242 /// If the asset was not found this is still called with the asset UUID but with a null asset data reference</param>
243 public void GetAsset(LLUUID assetId, AssetRequestCallback callback, bool isTexture) 243 public void GetAsset(LLUUID assetId, AssetRequestCallback callback, bool isTexture)
244 { 244 {
245 #if DEBUG
246 //m_log.DebugFormat("[ASSET CACHE]: Requesting {0} {1}", isTexture ? "texture" : "asset", assetId);
247 #endif
248
245 AssetBase asset; 249 AssetBase asset;
246 250
247 if (TryGetCachedAsset(assetId, out asset)) 251 if (TryGetCachedAsset(assetId, out asset))
@@ -249,11 +253,11 @@ namespace OpenSim.Framework.Communications.Cache
249 callback(assetId, asset); 253 callback(assetId, asset);
250 } 254 }
251 else 255 else
252 { 256 {
253 #if DEBUG 257 #if DEBUG
254 //m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId); 258 //m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId);
255 #endif 259 #endif
256 260
257 NewAssetRequest req = new NewAssetRequest(assetId, callback); 261 NewAssetRequest req = new NewAssetRequest(assetId, callback);
258 262
259 // Make sure we always have a request list to which to add the asset 263 // Make sure we always have a request list to which to add the asset
@@ -395,7 +399,7 @@ namespace OpenSim.Framework.Communications.Cache
395 public void AssetReceived(AssetBase asset, bool IsTexture) 399 public void AssetReceived(AssetBase asset, bool IsTexture)
396 { 400 {
397 #if DEBUG 401 #if DEBUG
398 m_log.DebugFormat("[ASSET CACHE]: Received {0} [{1}]", IsTexture ? "texture" : "asset", asset.FullID); 402 //m_log.DebugFormat("[ASSET CACHE]: Received {0} [{1}]", IsTexture ? "texture" : "asset", asset.FullID);
399 #endif 403 #endif
400 404
401 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server 405 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server
@@ -479,27 +483,7 @@ namespace OpenSim.Framework.Communications.Cache
479 // See IAssetReceiver 483 // See IAssetReceiver
480 public void AssetNotFound(LLUUID assetID) 484 public void AssetNotFound(LLUUID assetID)
481 { 485 {
482 //m_log.ErrorFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); 486 m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID);
483
484 // The 'image not found' packet needs to happen, but RequestedTextures is not actually used (should be cleaned up)
485 // It might also be better to do this in the TextureDownloadModule
486 /*
487 *
488 AssetRequest req;
489
490 if (RequestedTextures.TryGetValue(assetID, out req))
491 {
492 m_log.WarnFormat("[ASSET CACHE]: sending image not found for {0}", assetID);
493 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
494 notFound.ImageID.ID = assetID;
495 req.RequestUser.OutPacket(notFound, ThrottleOutPacketType.Unknown);
496 RequestedTextures.Remove(assetID);
497 }
498 else
499 {
500 m_log.ErrorFormat("[ASSET CACHE]: Asset [{0}] not found, but couldn't find any users to send to ", assetID);
501 }
502 */
503 487
504 // Notify requesters for this asset 488 // Notify requesters for this asset
505 lock (RequestLists) 489 lock (RequestLists)
diff --git a/OpenSim/Region/Environment/Interfaces/ITextureSender.cs b/OpenSim/Region/Environment/Interfaces/ITextureSender.cs
new file mode 100644
index 0000000..6ea08d0
--- /dev/null
+++ b/OpenSim/Region/Environment/Interfaces/ITextureSender.cs
@@ -0,0 +1,61 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30
31namespace OpenSim.Region.Environment.Interfaces
32{
33 /// <summary>
34 /// Interface for an object which can send texture information to a client
35 /// </summary>
36 public interface ITextureSender
37 {
38 /// <summary>
39 /// Are we in the process of sending the texture?
40 /// </summary>
41 bool Sending { get; set; }
42
43 /// <summary>
44 /// Has the texture send been cancelled?
45 /// </summary>
46 bool Cancel { get; set; }
47
48 /// <summary>
49 /// Update the non data properties of a texture request
50 /// </summary>
51 /// <param name="discardLevel"></param>
52 /// <param name="packetNumber"></param>
53 void UpdateRequest(int discardLevel, uint packetNumber);
54
55 /// <summary>
56 /// Send a texture packet to the client.
57 /// </summary>
58 /// <returns>True if the last packet has been sent, false otherwise.</returns>
59 bool SendTexturePacket();
60 }
61}
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
index c773f9e..2b2ac42 100644
--- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
@@ -52,7 +52,8 @@ namespace OpenSim.Region.Environment.Modules
52 /// <summary> 52 /// <summary>
53 /// There is one queue for all textures waiting to be sent, regardless of the requesting user. 53 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
54 /// </summary> 54 /// </summary>
55 private readonly BlockingQueue<TextureSender> m_queueSenders = new BlockingQueue<TextureSender>(); 55 private readonly BlockingQueue<ITextureSender> m_queueSenders
56 = new BlockingQueue<ITextureSender>();
56 57
57 /// <summary> 58 /// <summary>
58 /// Each user has their own texture download service. 59 /// Each user has their own texture download service.
@@ -135,17 +136,19 @@ namespace OpenSim.Region.Environment.Modules
135 /// <param name="userID"></param> 136 /// <param name="userID"></param>
136 /// <param name="textureService"></param> 137 /// <param name="textureService"></param>
137 /// <returns>Always returns true, since a service is created if one does not already exist</returns> 138 /// <returns>Always returns true, since a service is created if one does not already exist</returns>
138 private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService) 139 private bool TryGetUserTextureService(
140 IClientAPI client, out UserTextureDownloadService textureService)
139 { 141 {
140 lock (m_userTextureServices) 142 lock (m_userTextureServices)
141 { 143 {
142 if (m_userTextureServices.TryGetValue(userID, out textureService)) 144 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
143 { 145 {
144 return true; 146 return true;
145 } 147 }
146 148
147 textureService = new UserTextureDownloadService(m_scene, m_queueSenders); 149 textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
148 m_userTextureServices.Add(userID, textureService); 150 m_userTextureServices.Add(client.AgentId, textureService);
151
149 return true; 152 return true;
150 } 153 }
151 } 154 }
@@ -159,9 +162,10 @@ namespace OpenSim.Region.Environment.Modules
159 { 162 {
160 IClientAPI client = (IClientAPI) sender; 163 IClientAPI client = (IClientAPI) sender;
161 UserTextureDownloadService textureService; 164 UserTextureDownloadService textureService;
162 if (TryGetUserTextureService(client.AgentId, out textureService)) 165
166 if (TryGetUserTextureService(client, out textureService))
163 { 167 {
164 textureService.HandleTextureRequest(client, e); 168 textureService.HandleTextureRequest(e);
165 } 169 }
166 } 170 }
167 171
@@ -170,7 +174,7 @@ namespace OpenSim.Region.Environment.Modules
170 /// </summary> 174 /// </summary>
171 public void ProcessTextureSenders() 175 public void ProcessTextureSenders()
172 { 176 {
173 TextureSender sender = null; 177 ITextureSender sender = null;
174 178
175 while (true) 179 while (true)
176 { 180 {
@@ -206,7 +210,7 @@ namespace OpenSim.Region.Environment.Modules
206 /// Called when the texture has finished sending. 210 /// Called when the texture has finished sending.
207 /// </summary> 211 /// </summary>
208 /// <param name="sender"></param> 212 /// <param name="sender"></param>
209 private void TextureSent(TextureSender sender) 213 private void TextureSent(ITextureSender sender)
210 { 214 {
211 sender.Sending = false; 215 sender.Sending = false;
212 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID); 216 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID);
diff --git a/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs b/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs
new file mode 100644
index 0000000..f85e900
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs
@@ -0,0 +1,75 @@
1/*
2 * Created by SharpDevelop.
3 * User: caseyj
4 * Date: 25/02/2008
5 * Time: 21:30
6 *
7 * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 */
9
10using System;
11
12using libsecondlife;
13using libsecondlife.Packets;
14
15using OpenSim.Framework;
16using OpenSim.Region.Environment.Interfaces;
17
18namespace OpenSim.Region.Environment.Modules
19{
20 /// <summary>
21 /// Sends a 'texture not found' packet back to the client
22 /// </summary>
23 public class TextureNotFoundSender : ITextureSender
24 {
25 //private static readonly log4net.ILog m_log
26 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
27
28 private LLUUID m_textureId;
29 private IClientAPI m_client;
30
31 // See ITextureSender
32 public bool Sending
33 {
34 get { return false; }
35 set { m_sending = value; }
36 }
37
38 private bool m_sending = false;
39
40 // See ITextureSender
41 public bool Cancel
42 {
43 get { return false; }
44 set { m_cancel = value; }
45 }
46
47 private bool m_cancel = false;
48
49 public TextureNotFoundSender(IClientAPI client, LLUUID textureID)
50 {
51 m_client = client;
52 m_textureId = textureID;
53 }
54
55 // See ITextureSender
56 public void UpdateRequest(int discardLevel, uint packetNumber)
57 {
58 // Not need to implement since priority changes don't affect this operation
59 }
60
61 // See ITextureSender
62 public bool SendTexturePacket()
63 {
64 //m_log.InfoFormat(
65 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
66 // m_textureId);
67
68 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
69 notFound.ImageID.ID = m_textureId;
70 m_client.OutPacket(notFound, ThrottleOutPacketType.Unknown);
71
72 return true;
73 }
74 }
75}
diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/TextureSender.cs
index 056b8e1..3d097c8 100644
--- a/OpenSim/Region/Environment/Modules/TextureSender.cs
+++ b/OpenSim/Region/Environment/Modules/TextureSender.cs
@@ -31,6 +31,7 @@ using libsecondlife;
31using libsecondlife.Packets; 31using libsecondlife.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console; 33using OpenSim.Framework.Console;
34using OpenSim.Region.Environment.Interfaces;
34 35
35namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules
36{ 37{
@@ -38,7 +39,7 @@ namespace OpenSim.Region.Environment.Modules
38 /// A TextureSender handles the process of receiving a texture requested by the client from the 39 /// A TextureSender handles the process of receiving a texture requested by the client from the
39 /// AssetCache, and then sending that texture back to the client. 40 /// AssetCache, and then sending that texture back to the client.
40 /// </summary> 41 /// </summary>
41 public class TextureSender 42 public class TextureSender : ITextureSender
42 { 43 {
43 private static readonly log4net.ILog m_log 44 private static readonly log4net.ILog m_log
44 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 45 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -67,9 +68,25 @@ namespace OpenSim.Region.Environment.Modules
67 /// </summary> 68 /// </summary>
68 private int PacketCounter = 0; 69 private int PacketCounter = 0;
69 70
70 public bool Cancel = false; 71 // See ITextureSender
72 public bool Cancel
73 {
74 get { return false; }
75 set { m_cancel = value; }
76 }
77
78 private bool m_cancel = false;
79
80 // See ITextureSender
81 public bool Sending
82 {
83 get { return false; }
84 set { m_sending = value; }
85 }
86
87 private bool m_sending = false;
88
71 public bool ImageLoaded = false; 89 public bool ImageLoaded = false;
72 public bool Sending = false;
73 90
74 private IClientAPI RequestUser; 91 private IClientAPI RequestUser;
75 92
@@ -97,6 +114,7 @@ namespace OpenSim.Region.Environment.Modules
97 ImageLoaded = true; 114 ImageLoaded = true;
98 } 115 }
99 116
117 // See ITextureSender
100 public void UpdateRequest(int discardLevel, uint packetNumber) 118 public void UpdateRequest(int discardLevel, uint packetNumber)
101 { 119 {
102 RequestedDiscardLevel = discardLevel; 120 RequestedDiscardLevel = discardLevel;
@@ -104,12 +122,11 @@ namespace OpenSim.Region.Environment.Modules
104 PacketCounter = (int) StartPacketNumber; 122 PacketCounter = (int) StartPacketNumber;
105 } 123 }
106 124
107 /// <summary> 125 // See ITextureSender
108 /// Send a texture packet to the client.
109 /// </summary>
110 /// <returns>True if the last packet has been sent, false otherwise.</returns>
111 public bool SendTexturePacket() 126 public bool SendTexturePacket()
112 { 127 {
128 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
129
113 SendPacket(); 130 SendPacket();
114 counter++; 131 counter++;
115 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || 132 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
@@ -170,7 +187,7 @@ namespace OpenSim.Region.Environment.Modules
170 } 187 }
171 catch (ArgumentOutOfRangeException) 188 catch (ArgumentOutOfRangeException)
172 { 189 {
173 m_log.Error("[TEXTURE]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + 190 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
174 m_asset.FullID.ToString() ); 191 m_asset.FullID.ToString() );
175 return; 192 return;
176 } 193 }
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
index 8987a19..77829f0 100644
--- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
+++ b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
@@ -28,9 +28,13 @@
28 28
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31
31using libsecondlife; 32using libsecondlife;
33using libsecondlife.Packets;
34
32using OpenSim.Framework; 35using OpenSim.Framework;
33using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
37using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
35 39
36namespace OpenSim.Region.Environment.Modules 40namespace OpenSim.Region.Environment.Modules
@@ -54,12 +58,16 @@ namespace OpenSim.Region.Environment.Modules
54 /// Texture Senders are placed in this queue once they have received their texture from the asset 58 /// Texture Senders are placed in this queue once they have received their texture from the asset
55 /// cache. Another module actually invokes the send. 59 /// cache. Another module actually invokes the send.
56 /// </summary> 60 /// </summary>
57 private readonly BlockingQueue<TextureSender> m_sharedSendersQueue; 61 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
58 62
59 private readonly Scene m_scene; 63 private readonly Scene m_scene;
64
65 private readonly IClientAPI m_client;
60 66
61 public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue) 67 public UserTextureDownloadService(
68 IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue)
62 { 69 {
70 m_client = client;
63 m_scene = scene; 71 m_scene = scene;
64 m_sharedSendersQueue = sharedQueue; 72 m_sharedSendersQueue = sharedQueue;
65 } 73 }
@@ -68,9 +76,8 @@ namespace OpenSim.Region.Environment.Modules
68 /// Handle a texture request. This involves creating a texture sender and placing it on the 76 /// Handle a texture request. This involves creating a texture sender and placing it on the
69 /// previously passed in shared queue. 77 /// previously passed in shared queue.
70 /// </summary> 78 /// </summary>
71 /// <param name="client"> </param>
72 /// <param name="e"></param> 79 /// <param name="e"></param>
73 public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) 80 public void HandleTextureRequest(TextureRequestArgs e)
74 { 81 {
75 TextureSender textureSender; 82 TextureSender textureSender;
76 83
@@ -91,7 +98,7 @@ namespace OpenSim.Region.Environment.Modules
91 m_scene.AddPendingDownloads(1); 98 m_scene.AddPendingDownloads(1);
92 99
93 TextureSender requestHandler = 100 TextureSender requestHandler =
94 new TextureSender(client, e.DiscardLevel, e.PacketNumber); 101 new TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
95 m_textureSenders.Add(e.RequestedAssetID, requestHandler); 102 m_textureSenders.Add(e.RequestedAssetID, requestHandler);
96 103
97 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true); 104 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true);
@@ -118,6 +125,8 @@ namespace OpenSim.Region.Environment.Modules
118 /// <param name="texture"></param> 125 /// <param name="texture"></param>
119 public void TextureCallback(LLUUID textureID, AssetBase texture) 126 public void TextureCallback(LLUUID textureID, AssetBase texture)
120 { 127 {
128 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
129
121 lock (m_textureSenders) 130 lock (m_textureSenders)
122 { 131 {
123 TextureSender textureSender; 132 TextureSender textureSender;
@@ -129,13 +138,12 @@ namespace OpenSim.Region.Environment.Modules
129 // Needs investigation. 138 // Needs investigation.
130 if (texture == null || texture.Data == null) 139 if (texture == null || texture.Data == null)
131 { 140 {
132 // Right now, leaving it up to lower level asset server code to post the fact that 141 m_log.DebugFormat(
133 // this texture could not be found 142 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing TextureNotFoundSender for {0}",
134 143 textureID);
135 // TODO Send packet back to the client telling it not to expect the texture 144
136 145 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
137 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD]: Removing download stat for {0}", textureID); 146 EnqueueTextureSender(textureNotFoundSender);
138 m_scene.AddPendingDownloads(-1);
139 } 147 }
140 else 148 else
141 { 149 {
@@ -163,11 +171,10 @@ namespace OpenSim.Region.Environment.Modules
163 /// Place a ready texture sender on the processing queue. 171 /// Place a ready texture sender on the processing queue.
164 /// </summary> 172 /// </summary>
165 /// <param name="textureSender"></param> 173 /// <param name="textureSender"></param>
166 private void EnqueueTextureSender(TextureSender textureSender) 174 private void EnqueueTextureSender(ITextureSender textureSender)
167 { 175 {
168 textureSender.Cancel = false; 176 textureSender.Cancel = false;
169 textureSender.Sending = true; 177 textureSender.Sending = true;
170 textureSender.counter = 0;
171 178
172 if (!m_sharedSendersQueue.Contains(textureSender)) 179 if (!m_sharedSendersQueue.Contains(textureSender))
173 { 180 {