mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Revert "Fix dupe callbacks in VaultAddChildNode"
This reverts commit b393947cd5
.
The commit was seemingly harmless, but it created or otherwise uncovered
stack corruption deep inside the vault voodoo. While I would like to know
what was up, I'm tired of dealing with it. The crash addressed here was
fixed in a subsequent moul-scripts commit, so let's just toss this one.
This commit is contained in:
@ -246,27 +246,18 @@ struct VaultAgeInitTrans {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddChildNodeTrans {
|
struct AddChildNodeFetchTrans {
|
||||||
FVaultAddChildNodeCallback callback;
|
FVaultAddChildNodeCallback callback;
|
||||||
void * cbParam;
|
void * cbParam;
|
||||||
ENetError result;
|
ENetError result;
|
||||||
std::atomic<long> opCount;
|
std::atomic<long> opCount;
|
||||||
|
|
||||||
void CompleteOp();
|
AddChildNodeFetchTrans()
|
||||||
|
: callback(nil), cbParam(nil), result(kNetSuccess), opCount(0) { }
|
||||||
|
|
||||||
public:
|
AddChildNodeFetchTrans(FVaultAddChildNodeCallback _callback, void * _param)
|
||||||
AddChildNodeTrans()
|
|
||||||
: callback(nullptr), cbParam(nullptr), result(kNetSuccess), opCount(0) { }
|
|
||||||
|
|
||||||
AddChildNodeTrans(FVaultAddChildNodeCallback _callback, void * _param)
|
|
||||||
: callback(_callback), cbParam(_param), result(kNetSuccess), opCount(0) { }
|
: callback(_callback), cbParam(_param), result(kNetSuccess), opCount(0) { }
|
||||||
|
|
||||||
void AddOp() { ++opCount; }
|
|
||||||
|
|
||||||
static void VaultNodeAdded (
|
|
||||||
ENetError result,
|
|
||||||
void * param
|
|
||||||
);
|
|
||||||
static void VaultNodeFetched (
|
static void VaultNodeFetched (
|
||||||
ENetError result,
|
ENetError result,
|
||||||
void * param,
|
void * param,
|
||||||
@ -1003,38 +994,18 @@ void VaultAgeInitTrans::AgeInitCallback (
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* AddChildNodeTrans
|
* AddChildNodeFetchTrans
|
||||||
*
|
*
|
||||||
***/
|
***/
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void AddChildNodeTrans::CompleteOp() {
|
void AddChildNodeFetchTrans::VaultNodeRefsFetched (
|
||||||
if ((--opCount) == 0) {
|
|
||||||
if (callback)
|
|
||||||
callback(result, cbParam);
|
|
||||||
delete this; // commit hara-kiri
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void AddChildNodeTrans::VaultNodeAdded(
|
|
||||||
ENetError result,
|
|
||||||
void* param
|
|
||||||
) {
|
|
||||||
AddChildNodeTrans* trans = static_cast<AddChildNodeTrans*>(param);
|
|
||||||
if (IS_NET_ERROR(result))
|
|
||||||
trans->result = result;
|
|
||||||
trans->CompleteOp();
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
void AddChildNodeTrans::VaultNodeRefsFetched (
|
|
||||||
ENetError result,
|
ENetError result,
|
||||||
void * param,
|
void * param,
|
||||||
NetVaultNodeRef * refs,
|
NetVaultNodeRef * refs,
|
||||||
unsigned refCount
|
unsigned refCount
|
||||||
) {
|
) {
|
||||||
AddChildNodeTrans * trans = (AddChildNodeTrans *)param;
|
AddChildNodeFetchTrans * trans = (AddChildNodeFetchTrans *)param;
|
||||||
|
|
||||||
if (IS_NET_ERROR(result)) {
|
if (IS_NET_ERROR(result)) {
|
||||||
trans->result = result;
|
trans->result = result;
|
||||||
@ -1044,27 +1015,45 @@ void AddChildNodeTrans::VaultNodeRefsFetched (
|
|||||||
FetchNodesFromRefs(
|
FetchNodesFromRefs(
|
||||||
refs,
|
refs,
|
||||||
refCount,
|
refCount,
|
||||||
AddChildNodeTrans::VaultNodeFetched,
|
AddChildNodeFetchTrans::VaultNodeFetched,
|
||||||
param,
|
param,
|
||||||
&incFetchCount
|
&incFetchCount
|
||||||
);
|
);
|
||||||
trans->opCount += incFetchCount;
|
trans->opCount += incFetchCount;
|
||||||
}
|
}
|
||||||
trans->CompleteOp();
|
|
||||||
|
// Make the callback now if there are no nodes to fetch, or if error
|
||||||
|
if (!(--trans->opCount)) {
|
||||||
|
if (trans->callback)
|
||||||
|
trans->callback(
|
||||||
|
trans->result,
|
||||||
|
trans->cbParam
|
||||||
|
);
|
||||||
|
delete trans;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void AddChildNodeTrans::VaultNodeFetched (
|
void AddChildNodeFetchTrans::VaultNodeFetched (
|
||||||
ENetError result,
|
ENetError result,
|
||||||
void * param,
|
void * param,
|
||||||
NetVaultNode * node
|
NetVaultNode * node
|
||||||
) {
|
) {
|
||||||
::VaultNodeFetched(result, param, node);
|
::VaultNodeFetched(result, param, node);
|
||||||
|
|
||||||
AddChildNodeTrans * trans = (AddChildNodeTrans *)param;
|
AddChildNodeFetchTrans * trans = (AddChildNodeFetchTrans *)param;
|
||||||
|
|
||||||
if (IS_NET_ERROR(result))
|
if (IS_NET_ERROR(result))
|
||||||
trans->result = result;
|
trans->result = result;
|
||||||
trans->CompleteOp();
|
|
||||||
|
if (!(--trans->opCount)) {
|
||||||
|
if (trans->callback)
|
||||||
|
trans->callback(
|
||||||
|
trans->result,
|
||||||
|
trans->cbParam
|
||||||
|
);
|
||||||
|
delete trans;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1748,6 +1737,9 @@ void VaultAddChildNode (
|
|||||||
FVaultAddChildNodeCallback callback,
|
FVaultAddChildNodeCallback callback,
|
||||||
void * param
|
void * param
|
||||||
) {
|
) {
|
||||||
|
// Make sure we only do the callback once
|
||||||
|
bool madeCallback = false;
|
||||||
|
|
||||||
// Too much of the client relies on the assumption that the node will be immediately
|
// Too much of the client relies on the assumption that the node will be immediately
|
||||||
// associated with its parent. THIS SUCKS, because there's no way to guarantee the
|
// associated with its parent. THIS SUCKS, because there's no way to guarantee the
|
||||||
// association won't be circular (the db checks this in a comprehensive way).
|
// association won't be circular (the db checks this in a comprehensive way).
|
||||||
@ -1756,14 +1748,14 @@ void VaultAddChildNode (
|
|||||||
// This directly affects: New clothing items added to the avatar outfit folder,
|
// This directly affects: New clothing items added to the avatar outfit folder,
|
||||||
// new chronicle entries in some ages, and I'm sure several other situations.
|
// new chronicle entries in some ages, and I'm sure several other situations.
|
||||||
|
|
||||||
AddChildNodeTrans * trans = nullptr;
|
|
||||||
if (RelVaultNodeLink * parentLink = s_nodes.Find(parentId)) {
|
if (RelVaultNodeLink * parentLink = s_nodes.Find(parentId)) {
|
||||||
RelVaultNodeLink * childLink = s_nodes.Find(childId);
|
RelVaultNodeLink * childLink = s_nodes.Find(childId);
|
||||||
if (!childLink) {
|
if (!childLink) {
|
||||||
childLink = new RelVaultNodeLink(false, ownerId, childId, new RelVaultNode);
|
childLink = new RelVaultNodeLink(false, ownerId, childId, new RelVaultNode);
|
||||||
childLink->node->SetNodeId_NoDirty(childId);
|
childLink->node->SetNodeId_NoDirty(childId);
|
||||||
s_nodes.Add(childLink);
|
s_nodes.Add(childLink);
|
||||||
} else if (ownerId) {
|
}
|
||||||
|
else if (ownerId) {
|
||||||
childLink->ownerId = ownerId;
|
childLink->ownerId = ownerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1778,17 +1770,14 @@ void VaultAddChildNode (
|
|||||||
// callback now with error code
|
// callback now with error code
|
||||||
if (callback)
|
if (callback)
|
||||||
callback(kNetErrCircularReference, param);
|
callback(kNetErrCircularReference, param);
|
||||||
// I don't really care what Eric thinks, if we believe it's a circular reference, it's evil
|
}
|
||||||
// to report a failure, then send it to the server anyway! That's just a bug WAITING
|
else if (childLink->node->IsParentOf(parentId, 255)) {
|
||||||
// to be uncovered, and I don't want to deal with it!
|
|
||||||
return;
|
|
||||||
} else if (childLink->node->IsParentOf(parentId, 255)) {
|
|
||||||
LogMsg(kLogDebug, L"Node relationship would be circular: p:%u, c:%u", parentId, childId);
|
LogMsg(kLogDebug, L"Node relationship would be circular: p:%u, c:%u", parentId, childId);
|
||||||
// callback now with error code
|
// callback now with error code
|
||||||
if (callback)
|
if (callback)
|
||||||
callback(kNetErrCircularReference, param);
|
callback(kNetErrCircularReference, param);
|
||||||
return;
|
}
|
||||||
} else {
|
else {
|
||||||
NetVaultNodeRef refs[] = {
|
NetVaultNodeRef refs[] = {
|
||||||
{ parentId, childId, ownerId }
|
{ parentId, childId, ownerId }
|
||||||
};
|
};
|
||||||
@ -1798,51 +1787,65 @@ void VaultAddChildNode (
|
|||||||
|
|
||||||
BuildNodeTree(refs, arrsize(refs), &newNodeIds, &existingNodeIds);
|
BuildNodeTree(refs, arrsize(refs), &newNodeIds, &existingNodeIds);
|
||||||
|
|
||||||
trans = new AddChildNodeTrans(callback, param);
|
|
||||||
if (!childLink->node->GetNodeType() || !parentLink->node->GetNodeType()) {
|
if (!childLink->node->GetNodeType() || !parentLink->node->GetNodeType()) {
|
||||||
// One or more nodes need to be fetched before the callback is made
|
// One or more nodes need to be fetched before the callback is made
|
||||||
|
AddChildNodeFetchTrans * trans = new AddChildNodeFetchTrans(callback, param);
|
||||||
if (!childLink->node->GetNodeType()) {
|
if (!childLink->node->GetNodeType()) {
|
||||||
trans->AddOp();
|
++trans->opCount;
|
||||||
NetCliAuthVaultNodeFetch(
|
NetCliAuthVaultNodeFetch(
|
||||||
childId,
|
childId,
|
||||||
AddChildNodeTrans::VaultNodeFetched,
|
AddChildNodeFetchTrans::VaultNodeFetched,
|
||||||
trans
|
trans
|
||||||
);
|
);
|
||||||
trans->AddOp();
|
++trans->opCount;
|
||||||
NetCliAuthVaultFetchNodeRefs(
|
NetCliAuthVaultFetchNodeRefs(
|
||||||
childId,
|
childId,
|
||||||
AddChildNodeTrans::VaultNodeRefsFetched,
|
AddChildNodeFetchTrans::VaultNodeRefsFetched,
|
||||||
trans
|
trans
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!parentLink->node->GetNodeType()) {
|
if (!parentLink->node->GetNodeType()) {
|
||||||
trans->AddOp();
|
++trans->opCount;
|
||||||
NetCliAuthVaultNodeFetch(
|
NetCliAuthVaultNodeFetch(
|
||||||
parentId,
|
parentId,
|
||||||
AddChildNodeTrans::VaultNodeFetched,
|
AddChildNodeFetchTrans::VaultNodeFetched,
|
||||||
trans
|
trans
|
||||||
);
|
);
|
||||||
trans->AddOp();
|
++trans->opCount;
|
||||||
NetCliAuthVaultFetchNodeRefs(
|
NetCliAuthVaultFetchNodeRefs(
|
||||||
parentId,
|
parentId,
|
||||||
AddChildNodeTrans::VaultNodeRefsFetched,
|
AddChildNodeFetchTrans::VaultNodeRefsFetched,
|
||||||
trans
|
trans
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// We have both nodes already, so make the callback now.
|
||||||
|
if (callback) {
|
||||||
|
callback(kNetSuccess, param);
|
||||||
|
madeCallback = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Parent doesn't exist locally (and we may not want it to), just make the callback now.
|
||||||
|
if (callback) {
|
||||||
|
callback(kNetSuccess, param);
|
||||||
|
madeCallback = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send it off to the vault. Note that we're reusing the old fetch trans's opCount junk
|
// Send it on up to the vault. The db server filters out duplicate and
|
||||||
// to ensure that we only ever callback once. May Jesus be with us all.
|
// circular node relationships. We send the request up even if we think
|
||||||
if (trans)
|
// the relationship would be circular since the db does a universal
|
||||||
trans->AddOp();
|
// check and is the only real authority in this matter.
|
||||||
NetCliAuthVaultNodeAdd(
|
NetCliAuthVaultNodeAdd(
|
||||||
parentId,
|
parentId,
|
||||||
childId,
|
childId,
|
||||||
ownerId,
|
ownerId,
|
||||||
trans ? AddChildNodeTrans::VaultNodeAdded : callback,
|
madeCallback ? nil : callback,
|
||||||
trans ? trans : param
|
madeCallback ? nil : param
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user