Fix how the mark-serial is used.
The mark-serial is a generation number to optimize dependency tracking. It did not actually get applied correctly, meaning that in rare cases we could miss dependencies. This patch removes the incorrect serial propagation and ensures that we don't double-count a dependent plugin. Additionally, this patch ensures that all callers of BindNativeToPlugin() will update the mark serial, as is required to correctly track dependencies.
This commit is contained in:
parent
9ef8cc7064
commit
0aaa659e29
@ -48,6 +48,7 @@ unsigned int CNativeOwner::GetMarkSerial()
|
|||||||
|
|
||||||
void CNativeOwner::AddDependent(CPlugin *pPlugin)
|
void CNativeOwner::AddDependent(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
|
if (m_Dependents.find(pPlugin) == m_Dependents.end())
|
||||||
m_Dependents.push_back(pPlugin);
|
m_Dependents.push_back(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,23 +65,8 @@ void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
|
|||||||
m_natives.append(natives);
|
m_natives.append(natives);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNativeOwner::PropagateMarkSerial(unsigned int serial)
|
|
||||||
{
|
|
||||||
CNativeOwner *pOwner;
|
|
||||||
List<CPlugin *>::iterator iter;
|
|
||||||
|
|
||||||
for (iter = m_Dependents.begin();
|
|
||||||
iter != m_Dependents.end();
|
|
||||||
iter++)
|
|
||||||
{
|
|
||||||
pOwner = (*iter);
|
|
||||||
pOwner->SetMarkSerial(serial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::UnbindWeakRef(const WeakNative &ref)
|
void CNativeOwner::UnbindWeakRef(const WeakNative &ref)
|
||||||
{
|
{
|
||||||
sp_native_t *native;
|
|
||||||
IPluginContext *pContext;
|
IPluginContext *pContext;
|
||||||
|
|
||||||
pContext = ref.pl->GetBaseContext();
|
pContext = ref.pl->GetBaseContext();
|
||||||
|
@ -69,7 +69,6 @@ public:
|
|||||||
public:
|
public:
|
||||||
void SetMarkSerial(unsigned int serial);
|
void SetMarkSerial(unsigned int serial);
|
||||||
unsigned int GetMarkSerial();
|
unsigned int GetMarkSerial();
|
||||||
void PropagateMarkSerial(unsigned int serial);
|
|
||||||
public:
|
public:
|
||||||
void AddDependent(CPlugin *pPlugin);
|
void AddDependent(CPlugin *pPlugin);
|
||||||
void AddWeakRef(const WeakNative & ref);
|
void AddWeakRef(const WeakNative & ref);
|
||||||
|
@ -1381,6 +1381,7 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
|
|||||||
|| pOther->GetStatus() == Plugin_Paused)
|
|| pOther->GetStatus() == Plugin_Paused)
|
||||||
&& pOther != pPlugin)
|
&& pOther != pPlugin)
|
||||||
{
|
{
|
||||||
|
g_ShareSys.BeginBindingFor(pPlugin);
|
||||||
for (size_t i = 0; i < pPlugin->m_fakes.length(); i++)
|
for (size_t i = 0; i < pPlugin->m_fakes.length(); i++)
|
||||||
g_ShareSys.BindNativeToPlugin(pOther, pPlugin->m_fakes[i]);
|
g_ShareSys.BindNativeToPlugin(pOther, pPlugin->m_fakes[i]);
|
||||||
}
|
}
|
||||||
|
@ -269,19 +269,19 @@ PassRef<Native> ShareSystem::FindNative(const char *name)
|
|||||||
return *r;
|
return *r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareSystem::BeginBindingFor(CPlugin *pPlugin)
|
||||||
|
{
|
||||||
|
g_mark_serial++;
|
||||||
|
}
|
||||||
|
|
||||||
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
||||||
{
|
{
|
||||||
uint32_t i, native_count;
|
IPluginContext *pContext = pPlugin->GetBaseContext();
|
||||||
IPluginContext *pContext;
|
|
||||||
|
|
||||||
pContext = pPlugin->GetBaseContext();
|
BeginBindingFor(pPlugin);
|
||||||
|
|
||||||
/* Generate a new serial ID, mark our dependencies with it. */
|
uint32_t native_count = pContext->GetNativesNum();
|
||||||
g_mark_serial++;
|
for (uint32_t i = 0; i < native_count; i++)
|
||||||
pPlugin->PropagateMarkSerial(g_mark_serial);
|
|
||||||
|
|
||||||
native_count = pContext->GetNativesNum();
|
|
||||||
for (i = 0; i < native_count; i++)
|
|
||||||
{
|
{
|
||||||
const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
|
const sp_native_t *native = pContext->GetRuntime()->GetNative(i);
|
||||||
if (!native)
|
if (!native)
|
||||||
@ -349,15 +349,12 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *native
|
|||||||
/* Otherwise, we're a strong dependent and not a weak one */
|
/* Otherwise, we're a strong dependent and not a weak one */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* See if this has already been marked as a dependent.
|
// If this plugin is not binding to itself, and it hasn't been marked as a
|
||||||
* If it has, it means this relationship has already occurred,
|
// dependency already, then add it now. We use the mark serial to track
|
||||||
* and there is no reason to do it again.
|
// which plugins we already consider a dependency.
|
||||||
*/
|
if (pEntry->owner != pPlugin->ToNativeOwner() &&
|
||||||
if (pEntry->owner != pPlugin->ToNativeOwner()
|
pEntry->owner->GetMarkSerial() != g_mark_serial)
|
||||||
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
|
|
||||||
{
|
{
|
||||||
/* This has not been marked as a dependency yet */
|
|
||||||
//pPlugin->AddDependency(pEntry->owner);
|
|
||||||
pEntry->owner->AddDependent(pPlugin);
|
pEntry->owner->AddDependent(pPlugin);
|
||||||
pEntry->owner->SetMarkSerial(g_mark_serial);
|
pEntry->owner->SetMarkSerial(g_mark_serial);
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ public:
|
|||||||
return &m_IdentRoot;
|
return &m_IdentRoot;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
void BeginBindingFor(CPlugin *pPlugin);
|
||||||
void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
|
void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
|
||||||
void BindNativeToPlugin(CPlugin *pPlugin, const ke::Ref<Native> &pEntry);
|
void BindNativeToPlugin(CPlugin *pPlugin, const ke::Ref<Native> &pEntry);
|
||||||
ke::PassRef<Native> AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
ke::PassRef<Native> AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
||||||
|
Loading…
Reference in New Issue
Block a user