Skip to content

Commit

Permalink
fixed invalidation of token
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Killat committed Nov 16, 2020
1 parent 91dbab4 commit a196aaf
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 37 deletions.
33 changes: 13 additions & 20 deletions include/waitset/waitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,6 @@ class WaitSet
return WaitToken(node);
}

bool remove(WaitToken &token)
{
auto id = token.id();
token.invalidate();
return remove(id);
}

bool remove(id_t id)
{
std::lock_guard g(m_nodesMutex);
auto &node = m_nodes[id];

//only remove it if no token references it anymore
if (node.numReferences() <= 0)
{
return m_nodes.remove(id);
}
return false;
}

//todo: we could also add a timed wait but in theory this can be done with a condition that is set to true by a timer

//we can only have one waiter for proper operation (concurrent condition result reset would cause problems!)
Expand Down Expand Up @@ -182,6 +162,19 @@ class WaitSet

//we do not want to add this to the container itself, we need a scoped lock for iteration
std::mutex m_nodesMutex;

bool remove(id_t id)
{
std::lock_guard g(m_nodesMutex);
auto &node = m_nodes[id];

//only remove it if no token references it anymore
if (node.numReferences() <= 0)
{
return m_nodes.remove(id);
}
return false;
}
};

//can only be defined when WaitSet is fully defined
Expand Down
9 changes: 4 additions & 5 deletions include/waitset/waittoken.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ class WaitToken
{
if (&rhs != this)
{
if (isValid())
{
m_waitNode->decrementRefCount();
}
invalidate();

m_waitNode = rhs.m_waitNode;
if (isValid())
Expand All @@ -47,6 +44,7 @@ class WaitToken
{
if (&rhs != this)
{
invalidate();
m_waitNode = rhs.m_waitNode;
rhs.m_waitNode = nullptr;
}
Expand Down Expand Up @@ -87,7 +85,8 @@ class WaitToken
{
if (isValid())
{
if (m_waitNode->decrementRefCount())
m_waitNode->decrementRefCount();
if (m_waitNode->numReferences() <= 0)
{
m_waitNode->tryDelete();
}
Expand Down
26 changes: 14 additions & 12 deletions test_waitset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,21 @@ int main(int argc, char **argv)
auto maybeToken = waitSet.add(always_true);
if (!maybeToken.has_value())
{
waitSet.remove(token3); //a copy of token1, if we do not remove it we cannot free the node (shared by token1 and token3)
std::cout << "could not get another token" << std::endl;
if (waitSet.remove(token1))
token1.invalidate();
token3.invalidate(); //invalidating both tokens (referencing the same node) will delete the node from the waitset

//we should have space again
//maybeToken = waitSet.add(always_false);
maybeToken = waitSet.add(always_true);
if (maybeToken.has_value())
{
token1 = *maybeToken;
token3 = token1;
std::cout << "regenerated token1 and its copy token3" << std::endl;
}
else
{
//we should have space again
//maybeToken = waitSet.add(always_false);
maybeToken = waitSet.add(always_true);
if (maybeToken.has_value())
{
token1 = *maybeToken;
token3 = token1;
std::cout << "regenerated token1 and its copy token3" << std::endl;
}
std::cout << "could not get another token" << std::endl;
}
}

Expand Down

0 comments on commit a196aaf

Please sign in to comment.