@@ -213,16 +213,30 @@ class LLMeshHeaderResponder : public LLHTTPClient::ResponderWithCompleted
213213{
214214public:
215215 LLVolumeParams mMeshParams ;
216-
216+ bool mProcessed ;
217+
217218 LLMeshHeaderResponder (const LLVolumeParams& mesh_params)
218219 : mMeshParams (mesh_params)
219220 {
220- LLMeshRepoThread::sActiveHeaderRequests ++;
221+ LLMeshRepoThread::incActiveHeaderRequests ();
222+ mProcessed = false ;
221223 }
222224
223225 ~LLMeshHeaderResponder ()
224226 {
225- LLMeshRepoThread::sActiveHeaderRequests --;
227+ if (!LLApp::isQuitting ())
228+ {
229+ if (!mProcessed )
230+ { // something went wrong, retry
231+ llwarns << " Timeout or service unavailable, retrying." << llendl;
232+ LLMeshRepository::sHTTPRetryCount ++;
233+ LLMeshRepoThread::HeaderRequest req (mMeshParams );
234+ LLMutexLock lock (gMeshRepo .mThread ->mMutex );
235+ gMeshRepo .mThread ->mHeaderReqQ .push (req);
236+ }
237+
238+ LLMeshRepoThread::decActiveHeaderRequests ();
239+ }
226240 }
227241
228242 /* virtual*/ void completedRaw (U32 status, const std::string& reason,
@@ -241,16 +255,27 @@ class LLMeshLODResponder : public LLHTTPClient::ResponderWithCompleted
241255 S32 mLOD ;
242256 U32 mRequestedBytes ;
243257 U32 mOffset ;
258+ bool mProcessed ;
244259
245260 LLMeshLODResponder (const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
246261 : mMeshParams (mesh_params), mLOD (lod), mOffset (offset), mRequestedBytes (requested_bytes)
247262 {
248- LLMeshRepoThread::sActiveLODRequests ++;
263+ LLMeshRepoThread::incActiveLODRequests ();
264+ mProcessed = false ;
249265 }
250266
251267 ~LLMeshLODResponder ()
252268 {
253- LLMeshRepoThread::sActiveLODRequests --;
269+ if (!LLApp::isQuitting ())
270+ {
271+ if (!mProcessed )
272+ {
273+ llwarns << " Killed without being processed, retrying." << llendl;
274+ LLMeshRepository::sHTTPRetryCount ++;
275+ gMeshRepo .mThread ->lockAndLoadMeshLOD (mMeshParams , mLOD );
276+ }
277+ LLMeshRepoThread::decActiveLODRequests ();
278+ }
254279 }
255280
256281 /* virtual*/ void completedRaw (U32 status, const std::string& reason,
@@ -268,10 +293,17 @@ class LLMeshSkinInfoResponder : public LLHTTPClient::ResponderWithCompleted
268293 LLUUID mMeshID ;
269294 U32 mRequestedBytes ;
270295 U32 mOffset ;
296+ bool mProcessed ;
271297
272298 LLMeshSkinInfoResponder (const LLUUID& id, U32 offset, U32 size)
273299 : mMeshID (id), mRequestedBytes (size), mOffset (offset)
274300 {
301+ mProcessed = false ;
302+ }
303+
304+ ~LLMeshSkinInfoResponder ()
305+ {
306+ llassert (mProcessed );
275307 }
276308
277309 /* virtual*/ void completedRaw (U32 status, const std::string& reason,
@@ -289,10 +321,17 @@ class LLMeshDecompositionResponder : public LLHTTPClient::ResponderWithCompleted
289321 LLUUID mMeshID ;
290322 U32 mRequestedBytes ;
291323 U32 mOffset ;
324+ bool mProcessed ;
292325
293326 LLMeshDecompositionResponder (const LLUUID& id, U32 offset, U32 size)
294327 : mMeshID (id), mRequestedBytes (size), mOffset (offset)
295328 {
329+ mProcessed = false ;
330+ }
331+
332+ ~LLMeshDecompositionResponder ()
333+ {
334+ llassert (mProcessed );
296335 }
297336
298337 /* virtual*/ void completedRaw (U32 status, const std::string& reason,
@@ -310,10 +349,17 @@ class LLMeshPhysicsShapeResponder : public LLHTTPClient::ResponderWithCompleted
310349 LLUUID mMeshID ;
311350 U32 mRequestedBytes ;
312351 U32 mOffset ;
352+ bool mProcessed ;
313353
314354 LLMeshPhysicsShapeResponder (const LLUUID& id, U32 offset, U32 size)
315355 : mMeshID (id), mRequestedBytes (size), mOffset (offset)
316356 {
357+ mProcessed = false ;
358+ }
359+
360+ ~LLMeshPhysicsShapeResponder ()
361+ {
362+ llassert (mProcessed );
317363 }
318364
319365 /* virtual*/ void completedRaw (U32 status, const std::string& reason,
@@ -680,16 +726,22 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
680726 mPhysicsShapeRequests .insert (mesh_id);
681727}
682728
729+ void LLMeshRepoThread::lockAndLoadMeshLOD (const LLVolumeParams& mesh_params, S32 lod)
730+ {
731+ if (!LLAppViewer::isQuitting ())
732+ {
733+ loadMeshLOD (mesh_params, lod);
734+ }
735+ }
683736
684737void LLMeshRepoThread::loadMeshLOD (const LLVolumeParams& mesh_params, S32 lod)
685- { // protected by mSignal, no locking needed here
686-
738+ { // could be called from any thread
739+ LLMutexLock lock ( mMutex );
687740 mesh_header_map::iterator iter = mMeshHeader .find (mesh_params.getSculptID ());
688741 if (iter != mMeshHeader .end ())
689742 { // if we have the header, request LOD byte range
690743 LODRequest req (mesh_params, lod);
691744 {
692- LLMutexLock lock (mMutex );
693745 mLODReqQ .push (req);
694746 LLMeshRepository::sLODProcessing ++;
695747 }
@@ -707,7 +759,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
707759 }
708760 else
709761 { // if no header request is pending, fetch header
710- LLMutexLock lock (mMutex );
711762 mHeaderReqQ .push (req);
712763 mPendingLOD [mesh_params].push_back (lod);
713764 }
@@ -961,6 +1012,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
9611012 return true ;
9621013}
9631014
1015+ // static
1016+ void LLMeshRepoThread::incActiveLODRequests ()
1017+ {
1018+ LLMutexLock lock (gMeshRepo .mThread ->mMutex );
1019+ ++LLMeshRepoThread::sActiveLODRequests ;
1020+ }
1021+
1022+ // static
1023+ void LLMeshRepoThread::decActiveLODRequests ()
1024+ {
1025+ LLMutexLock lock (gMeshRepo .mThread ->mMutex );
1026+ --LLMeshRepoThread::sActiveLODRequests ;
1027+ }
1028+
1029+ // static
1030+ void LLMeshRepoThread::incActiveHeaderRequests ()
1031+ {
1032+ LLMutexLock lock (gMeshRepo .mThread ->mMutex );
1033+ ++LLMeshRepoThread::sActiveHeaderRequests ;
1034+ }
1035+
1036+ // static
1037+ void LLMeshRepoThread::decActiveHeaderRequests ()
1038+ {
1039+ LLMutexLock lock (gMeshRepo .mThread ->mMutex );
1040+ --LLMeshRepoThread::sActiveHeaderRequests ;
1041+ }
1042+
9641043// return false if failed to get header
9651044bool LLMeshRepoThread::fetchMeshHeader (const LLVolumeParams& mesh_params, U32& count)
9661045{
@@ -1776,7 +1855,8 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
17761855 const LLChannelDescriptors& channels,
17771856 const LLIOPipe::buffer_ptr_t & buffer)
17781857{
1779-
1858+ mProcessed = true ;
1859+
17801860 S32 data_size = buffer->countAfter (channels.in (), NULL );
17811861
17821862 if (status < 200 || status >= 400 )
@@ -1788,6 +1868,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
17881868 {
17891869 if (is_internal_http_error_that_warrants_a_retry (status) || status == HTTP_SERVICE_UNAVAILABLE)
17901870 { // timeout or service unavailable, try again
1871+ llwarns << " Timeout or service unavailable, retrying." << llendl;
17911872 LLMeshRepository::sHTTPRetryCount ++;
17921873 gMeshRepo .mThread ->loadMeshLOD (mMeshParams , mLOD );
17931874 }
@@ -1831,6 +1912,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
18311912 const LLChannelDescriptors& channels,
18321913 const LLIOPipe::buffer_ptr_t & buffer)
18331914{
1915+ mProcessed = true ;
1916+
18341917 S32 data_size = buffer->countAfter (channels.in (), NULL );
18351918
18361919 if (status < 200 || status >= 400 )
@@ -1842,6 +1925,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
18421925 {
18431926 if (is_internal_http_error_that_warrants_a_retry (status) || status == HTTP_SERVICE_UNAVAILABLE)
18441927 { // timeout or service unavailable, try again
1928+ llwarns << " Timeout or service unavailable, retrying." << llendl;
18451929 LLMeshRepository::sHTTPRetryCount ++;
18461930 gMeshRepo .mThread ->loadMeshSkinInfo (mMeshID );
18471931 }
@@ -1885,6 +1969,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
18851969 const LLChannelDescriptors& channels,
18861970 const LLIOPipe::buffer_ptr_t & buffer)
18871971{
1972+ mProcessed = true ;
1973+
18881974 S32 data_size = buffer->countAfter (channels.in (), NULL );
18891975
18901976 if (status < 200 || status >= 400 )
@@ -1896,6 +1982,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
18961982 {
18971983 if (is_internal_http_error_that_warrants_a_retry (status) || status == HTTP_SERVICE_UNAVAILABLE)
18981984 { // timeout or service unavailable, try again
1985+ llwarns << " Timeout or service unavailable, retrying." << llendl;
18991986 LLMeshRepository::sHTTPRetryCount ++;
19001987 gMeshRepo .mThread ->loadMeshDecomposition (mMeshID );
19011988 }
@@ -1939,6 +2026,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
19392026 const LLChannelDescriptors& channels,
19402027 const LLIOPipe::buffer_ptr_t & buffer)
19412028{
2029+ mProcessed = true ;
2030+
19422031 S32 data_size = buffer->countAfter (channels.in (), NULL );
19432032
19442033 if (status < 200 || status >= 400 )
@@ -1950,6 +2039,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
19502039 {
19512040 if (is_internal_http_error_that_warrants_a_retry (status) || status == HTTP_SERVICE_UNAVAILABLE)
19522041 { // timeout or service unavailable, try again
2042+ llwarns << " Timeout or service unavailable, retrying." << llendl;
19532043 LLMeshRepository::sHTTPRetryCount ++;
19542044 gMeshRepo .mThread ->loadMeshPhysicsShape (mMeshID );
19552045 }
@@ -1993,6 +2083,8 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
19932083 const LLChannelDescriptors& channels,
19942084 const LLIOPipe::buffer_ptr_t & buffer)
19952085{
2086+ mProcessed = true ;
2087+
19962088 if (status < 200 || status >= 400 )
19972089 {
19982090 // llwarns
@@ -2007,13 +2099,18 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
20072099 // again after some set period of time
20082100 if (is_internal_http_error_that_warrants_a_retry (status) || status == HTTP_SERVICE_UNAVAILABLE)
20092101 { // retry
2102+ llwarns << " Timeout or service unavailable, retrying." << llendl;
20102103 LLMeshRepository::sHTTPRetryCount ++;
20112104 LLMeshRepoThread::HeaderRequest req (mMeshParams );
20122105 LLMutexLock lock (gMeshRepo .mThread ->mMutex );
20132106 gMeshRepo .mThread ->mHeaderReqQ .push (req);
20142107
20152108 return ;
20162109 }
2110+ else
2111+ {
2112+ llwarns << " Unhandled status." << llendl;
2113+ }
20172114 }
20182115
20192116 S32 data_size = buffer->countAfter (channels.in (), NULL );
@@ -2028,7 +2125,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
20282125
20292126 LLMeshRepository::sBytesReceived += llmin (data_size, 4096 );
20302127
2031- if (!gMeshRepo .mThread ->headerReceived (mMeshParams , data, data_size))
2128+ bool success = gMeshRepo .mThread ->headerReceived (mMeshParams , data, data_size);
2129+
2130+ llassert (success);
2131+
2132+ if (!success)
20322133 {
20332134 llwarns
20342135 << " Unable to parse mesh header: "
0 commit comments