Closed MartinoMensio closed 7 years ago
Simplify where possible, also considering that not all the requirements of part A need to be implemented.
For example the deleteNFFG is not required (which causes the majority of sync problems).
So maybe it is sufficient to have ConcurrentMap to guarantee atomicity
The synchronization without considering the removal of NFFGs is simply obtained by using ConcurrentMap.
storeNffg
performs a single atomic operation on the nffgs map: a putIfAbsent
that is checking the existence and storing the new nffg in atomic waystorePolicy
is checking the references to nffg and nodes (src and dst) then is putting the new policy into the policies map. But since an NFFG cannot be deleted, after the check the references cannot be invalidated in any ways, so also in this case there is no need of additional synchronizationdeletePolicy
is removing the policy from the map of policies in a single atomic operationupdatePolicyResult
is first getting the policy from its name then is verifying its result. Also if this is not a single operation and a deletion can occur in between, this is not a problem because in this case the serialized view of the events would be that the deletion occurred after the update of the result, without side effects because the update of the result does not operate on the map but only on an object that is stored inside it, and can be safely removed from the map preventing other threads to reach this policy that still exist for the thread that is handling the updateverifyResultOnTheFly
is first validating the references contained in the policy (nffg, src, dst) and then verifying the result. Since the referenced nffg cannot be deleted (or updated) the data are still valid also if these operations are not performed atomicallyConsidering also the deletion, the modifications done are the following:
deleteNffg
method. In this way, when this lock is acquired no other threads can operate on the policies (modification)In details the usage of locks by each method:
deleteNffg
in the critical section protected by exclusive lock is:
storePolicy
uses a shared lock to validate the references and then storing in the policies map the new one. In this way the removal cannot occur between the two operations, and therefore the references are still validdeletePolcy
uses a shared lock because the iteration that is occurring in the deleteNffg
over the collection of policies acts on the valueSet that is not explicitly concurrent-safe also if it coming from a ConcurrentMap. In order to avoid any problems, the deletion of a single policy is done in a protected blockupdatePolicyResult
uses the shared lock because after getting the policy from the name the verification is accessing the related nffg in order to use the ids, that must not be deleted between the two operationsverifyResultOnTheFly
uses the shared lock because after checking the references, the nffg must continue to be stored inside the nffgs mapstoreNffg
does not need any locks because acts on completely new data. If the nffg stored with the same name is still being removed but not yet from the map, the serialized view of events will have the store before the deletion, without causing side effects.getPolicies
is the only critical getter, that could give back a partial set of policies because the method removeIf
called on the entrySet by the deleteNffg
could be iterating and having removed only some policies belonging to the nffg that is being deleted. To avoid this problem, this method also uses the shared lockimplemented
Manage concurrent access to data