Fix for AIStateMachineThread (LLThreadSafeRefCount: deleting non-zero reference)

This fixes
https://code.google.com/p/singularity-viewer/issues/detail?id=736

The problem was that we need to keep the 'user' derived THREAD_IMPL
alive in the thread, and therefore used an LLPointer<THREAD_IMPL>
(as base class of AIStateMachineThread<THREAD_IMPL>), and therefore
THREAD_IMPL, derived from AIThreadImpl had to be derived from
LLThreadSafeRefCount. However, AIStateMachineThread<THREAD_IMPL> also
needed to be a statemachine of itself and is derived from
AIStateMachineThreadBase derived from AIStateMachine which is ALSO
derived from LLThreadSafeRefCount - that in this case wasn't really
needed. An attempt to deactive it by calling ref() from the constructor
of AIStateMachineThreadBase failed on the fact that LLThreadSafeRefCount
insists that its ref count mRef is exactly zero when it is being
deleted.

The chosen solution is to remove the ref count from AIThreadImpl and use
the LLThreadSafeRefCount base class of AIStateMachineThreadBase. The
result is that not only THREAD_IMPL, but also the state machine object
is kept alive, but that doesn't seem like a problem.

Thus, instead of passing a AIThreadImpl* to
AIStateMachineThreadBase::Thread, we now pass a
AIStateMachineThreadBase* to it to keep the whole of the
AIStateMachineThread<THREAD_IMPL> object alive, which has a THREAD_IMPL
as member now. This member then can be accessed through a virtual
function impl(). Another result of this change is that the 'user' (the
class derived from AIThreadImpl, THREAD_IMPL) now has to deal with the
LLPointer, and use LLPointer<AIStateMachineThread<THREAD_IMPL> >
instead of just AIStateMachineThread<THREAD_IMPL> and also allocate
this object himself. The access from there then changes into a -> to
access the state machine (as opposed to a .) and ->thread_impl() to
access the THREAD_IMPL object (as opposed to a ->).
This commit is contained in:
Aleric Inglewood
2013-04-20 04:28:23 +02:00
parent b5e70e11c4
commit e0aa3489f8
4 changed files with 43 additions and 32 deletions

View File

@@ -1329,9 +1329,10 @@ void LLMeshUploadThread::preStart()
}
AIMeshUpload::AIMeshUpload(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, std::string const& upload_url, bool do_upload,
LLHandle<LLWholeModelFeeObserver> const& fee_observer, LLHandle<LLWholeModelUploadObserver> const& upload_observer) : mWholeModelUploadURL(upload_url)
LLHandle<LLWholeModelFeeObserver> const& fee_observer, LLHandle<LLWholeModelUploadObserver> const& upload_observer) :
mMeshUpload(new AIStateMachineThread<LLMeshUploadThread>), mWholeModelUploadURL(upload_url)
{
mMeshUpload->init(data, scale, upload_textures, upload_skin, upload_joints, do_upload, fee_observer, upload_observer);
mMeshUpload->thread_impl().init(data, scale, upload_textures, upload_skin, upload_joints, do_upload, fee_observer, upload_observer);
}
char const* AIMeshUpload::state_str_impl(state_type run_state) const
@@ -1347,7 +1348,7 @@ char const* AIMeshUpload::state_str_impl(state_type run_state) const
void AIMeshUpload::initialize_impl()
{
mMeshUpload->preStart();
mMeshUpload->thread_impl().preStart();
set_state(AIMeshUpload_start);
}
@@ -1356,11 +1357,11 @@ void AIMeshUpload::multiplex_impl(state_type run_state)
switch (run_state)
{
case AIMeshUpload_start:
mMeshUpload.run(this, AIMeshUpload_threadFinished);
mMeshUpload->run(this, AIMeshUpload_threadFinished);
idle(); // Wait till the thread finished.
break;
case AIMeshUpload_threadFinished:
mMeshUpload->postRequest(mWholeModelUploadURL, this);
mMeshUpload->thread_impl().postRequest(mWholeModelUploadURL, this);
idle(); // Wait till the responder finished.
break;
case AIMeshUpload_responderFinished:

View File

@@ -433,7 +433,7 @@ enum AIMeshUpload_state_type {
class AIMeshUpload : public AIStateMachine
{
private:
AIStateMachineThread<LLMeshUploadThread> mMeshUpload;
LLPointer<AIStateMachineThread<LLMeshUploadThread> > mMeshUpload;
std::string mWholeModelUploadURL;
public: