FIRE-22962: Attempt at fixing the bridge creation crash: Use timer only to signal state change and perform actions during idle callbacks

master
Ansariel 2018-08-22 20:17:05 +02:00
parent 216c3affae
commit d41999865f
2 changed files with 77 additions and 35 deletions

View File

@ -93,14 +93,56 @@ FSLSLBridge::FSLSLBridge():
mpBridge(NULL),
mIsFirstCallDone(false),
mAllowDetach(false),
mFinishCreation(false)
mFinishCreation(false),
mTimerResult(FSLSLBridge::NO_TIMER)
{
LL_INFOS("FSLSLBridge") << "Constructing FSLSLBridge" << LL_ENDL;
mCurrentFullName = llformat("%s%d.%d", FS_BRIDGE_NAME.c_str(), FS_BRIDGE_MAJOR_VERSION, FS_BRIDGE_MINOR_VERSION);
gIdleCallbacks.addFunction(onIdle, this);
}
FSLSLBridge::~FSLSLBridge()
{
gIdleCallbacks.deleteFunction(onIdle, this);
}
void FSLSLBridge::onIdle(void* userdata)
{
FSLSLBridge* instance = static_cast<FSLSLBridge*>(userdata);
if (instance)
{
switch (instance->mTimerResult)
{
case START_CREATION_FINISHED:
instance->finishCleanUpPreCreation();
instance->setTimerResult(NO_TIMER);
break;
case CLEANUP_FINISHED:
instance->finishBridge();
instance->setTimerResult(NO_TIMER);
break;
case REATTACH_FINISHED:
{
LLViewerInventoryItem* inv_object = gInventory.getItem(instance->mReattachBridgeUUID);
if (inv_object && instance->getBridge() && instance->getBridge()->getUUID() == inv_object->getUUID())
{
LLAttachmentsMgr::instance().addAttachmentRequest(inv_object->getUUID(), FS_BRIDGE_POINT, TRUE, TRUE);
}
instance->mReattachBridgeUUID.setNull();
instance->setTimerResult(NO_TIMER);
}
break;
case NO_TIMER:
default:
break;
}
}
}
void FSLSLBridge::setTimerResult(TimerResult result)
{
mTimerResult = result;
}
bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID)
@ -979,7 +1021,8 @@ void FSLSLBridge::processDetach(LLViewerObject* object, const LLViewerJointAttac
if (mFinishCreation)
{
LL_INFOS("FSLSLBridge") << "Bridge detached to save settings. Starting re-attach timer..." << LL_ENDL;
new FSLSLBridgeReAttachTimer(object->getAttachmentItemID());
mReattachBridgeUUID = object->getAttachmentItemID();
new FSLSLBridgeReAttachTimer();
return;
}
@ -1325,15 +1368,7 @@ void FSLSLBridge::checkBridgeScriptName()
return;
}
obj->saveScript(gInventory.getItem(mScriptItemID), TRUE, false);
FSLSLBridgeCleanupTimer* objTimer = new FSLSLBridgeCleanupTimer(1.0f);
objTimer->startTimer();
}
BOOL FSLSLBridgeCleanupTimer::tick()
{
stopTimer();
FSLSLBridge::instance().finishBridge();
return TRUE;
new FSLSLBridgeCleanupTimer();
}
void FSLSLBridge::cleanUpBridge()
@ -1590,16 +1625,21 @@ void FSLSLBridge::detachOtherBridges()
}
}
BOOL FSLSLBridgeReAttachTimer::tick()
BOOL FSLSLBridgeCleanupTimer::tick()
{
LL_INFOS("FSLSLBridge") << "Re-attaching bridge after creation..." << LL_ENDL;
mEventTimer.stop();
LLViewerInventoryItem* inv_object = gInventory.getItem(mBridgeUUID);
if (inv_object && FSLSLBridge::instance().mpBridge && FSLSLBridge::instance().mpBridge->getUUID() == inv_object->getUUID())
{
LLAttachmentsMgr::instance().addAttachmentRequest(inv_object->getUUID(), FS_BRIDGE_POINT, TRUE, TRUE);
}
FSLSLBridge::instance().setTimerResult(FSLSLBridge::CLEANUP_FINISHED);
return TRUE;
}
BOOL FSLSLBridgeReAttachTimer::tick()
{
LL_INFOS("FSLSLBridge") << "Re-attaching bridge after creation..." << LL_ENDL;
FSLSLBridge::instance().setTimerResult(FSLSLBridge::REATTACH_FINISHED);
return TRUE;
}
BOOL FSLSLBridgeStartCreationTimer::tick()
{
FSLSLBridge::instance().setTimerResult(FSLSLBridge::START_CREATION_FINISHED);
return TRUE;
}

View File

@ -54,6 +54,14 @@ class FSLSLBridge : public LLSingleton<FSLSLBridge>, public LLVOInventoryListene
~FSLSLBridge();
public:
enum TimerResult
{
START_CREATION_FINISHED,
CLEANUP_FINISHED,
REATTACH_FINISHED,
NO_TIMER
};
typedef boost::function<void(const LLSD &)> tCallback;
bool lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID);
@ -84,6 +92,9 @@ public:
bool canDetach(const LLUUID& item_id);
static void onIdle(void* userdata);
void setTimerResult(TimerResult result);
// from LLVOInventoryListener
virtual void inventoryChanged(LLViewerObject* object,
LLInventoryObject::object_list_t* inventory,
@ -102,11 +113,14 @@ private:
LLUUID mBridgeFolderID;
LLUUID mBridgeContainerFolderID;
LLUUID mBridgeUUID;
LLUUID mReattachBridgeUUID; // used when re-attachming the bridge after creation
bool mIsFirstCallDone; //initialization conversation
uuid_vec_t mAllowedDetachables;
TimerResult mTimerResult;
protected:
LLViewerInventoryItem* findInvObject(const std::string& obj_name, const LLUUID& catID);
LLUUID findFSCategory();
@ -177,33 +191,21 @@ protected:
class FSLSLBridgeCleanupTimer : public LLEventTimer
{
public:
FSLSLBridgeCleanupTimer(F32 period) : LLEventTimer(period) {}
FSLSLBridgeCleanupTimer() : LLEventTimer(1.f) {}
BOOL tick();
void startTimer() { mEventTimer.start(); }
void stopTimer() { mEventTimer.stop(); }
};
class FSLSLBridgeReAttachTimer : public LLEventTimer
{
public:
FSLSLBridgeReAttachTimer(const LLUUID& bridge_uuid) :
LLEventTimer(5.f),
mBridgeUUID(bridge_uuid)
{}
FSLSLBridgeReAttachTimer() : LLEventTimer(5.f) {}
BOOL tick();
protected:
LLUUID mBridgeUUID;
};
class FSLSLBridgeStartCreationTimer : public LLEventTimer
{
public:
FSLSLBridgeStartCreationTimer() : LLEventTimer(5.f) {}
BOOL tick()
{
FSLSLBridge::instance().finishCleanUpPreCreation();
return TRUE;
}
BOOL tick();
};
#endif // FS_LSLBRIDGE_H