Changeset c296c2


Ignore:
Timestamp:
Feb 25, 2010, 2:32:35 PM (15 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
f59d81
Parents:
9b6b2f
Message:

MEMLEAK: Observable::signOff() erases its own iterator, some more documentation added

  • Observable::signOff() erases a given Observer from the Observer list, but it had no backup iterator to go on afterwards.
Location:
src/Patterns
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Patterns/Observer.cpp

    r9b6b2f rc296c2  
    2424// See [Gamma et al, 1995] p. 297
    2525
    26 map<Observable*, int> Observable::depth;
    27 map<Observable*,multimap<int,Observer*>*> Observable::callTable;
    28 set<Observable*> Observable::busyObservables;
    29 
    30 // The two functions start_observer_internal and finish_observer_internal
    31 // have to be used together at all time. Never use these functions directly
    32 // START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
    33 // thus producing compiler-errors whenever only one is used
    34 
     26map<Observable*, int> Observable::depth;  //!< Map of Observables to the depth of the DAG of Observers
     27map<Observable*,multimap<int,Observer*>*> Observable::callTable; //!< Table for each Observable of all its Observers
     28set<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers
     29
     30/** Attaching Sub-observables to Observables.
     31 * Increases entry in Observable::depth for this \a *publisher by one.
     32 *
     33 * The two functions \sa start_observer_internal() and \sa finish_observer_internal()
     34 * have to be used together at all time. Never use these functions directly
     35 * START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
     36 * thus producing compiler-errors whenever only one is used.
     37 * \param *publisher reference of sub-observable
     38 */
    3539void Observable::start_observer_internal(Observable *publisher){
    3640  // increase the count for this observable by one
     
    4044}
    4145
     46/** Detaching Sub-observables from Observables.
     47 * Decreases entry in Observable::depth for this \a *publisher by one. If zero, we
     48 * start notifying all our Observers.
     49 *
     50 * The two functions start_observer_internal() and finish_observer_internal()
     51 * have to be used together at all time. Never use these functions directly
     52 * START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
     53 * thus producing compiler-errors whenever only one is used.
     54 * \param *publisher reference of sub-observable
     55 */
    4256void Observable::finish_observer_internal(Observable *publisher){
    4357  // decrease the count for this observable
     
    5367}
    5468
     69/** Constructor for Observable Protector.
     70 * Basically, calls start_observer_internal(). Hence use this class instead of
     71 * calling the function directly.
     72 *
     73 * \param *protege Observable to be protected.
     74 */
    5575Observable::_Observable_protector::_Observable_protector(Observable *_protege) :
    5676  protege(_protege)
     
    5979}
    6080
     81/** Destructor for Observable Protector.
     82 * Basically, calls finish_observer_internal(). Hence use this class instead of
     83 * calling the function directly.
     84 *
     85 * \param *protege Observable to be protected.
     86 */
    6187Observable::_Observable_protector::~_Observable_protector()
    6288{
     
    6692/************* Notification mechanism for observables **************/
    6793
    68 
     94/** Notify all Observers of changes.
     95 * Puts \a *this into Observable::busyObservables, calls Observer::update() for all in callee_t
     96 * and removes from busy list.
     97 */
    6998void Observable::notifyAll() {
    7099  // we are busy notifying others right now
     
    87116}
    88117
    89 // this handles passing on updates from sub-Observables
     118/** Handles passing on updates from sub-Observables.
     119 * Mimicks basically the Observer::update() function.
     120 *
     121 * \param *publisher The \a *this we observe.
     122 */
    90123void Observable::update(Observable *publisher) {
    91124  // circle detection
     
    109142}
    110143
    111 // methods to sign-on and off
     144/** Sign on an Observer to this Observable.
     145 * Puts \a *target into Observable::callTable list.
     146 * \param *target Observer
     147 * \param priority number in [-20,20]
     148 */
    112149void Observable::signOn(Observer *target,int priority) {
    113150  assert(priority>=-20 && priority<=+20 && "Priority out of range [-20:+20]");
     
    130167}
    131168
     169/** Sign off an Observer from this Observable.
     170 * Removes \a *target from Observable::callTable list.
     171 * \param *target Observer
     172 */
    132173void Observable::signOff(Observer *target) {
    133174  assert(callTable.count(this) && "SignOff called for an Observable without Observers.");
    134175  callees_t *callees = callTable[this];
    135176  callees_t::iterator iter;
    136   for(iter=callees->begin();iter!=callees->end();iter++) {
    137     if((*iter).second == target)
    138       callees->erase(iter);
     177  callees_t::iterator deliter;
     178  for(iter=callees->begin();iter!=callees->end();) {
     179    deliter=iter++;
     180    if((*deliter).second == target)
     181      callees->erase(deliter);
    139182  }
    140183  if(callees->empty()){
     
    144187}
    145188
    146 // when an sub-observerable dies we usually don't need to do anything
     189/** Handles sub-observables that just got killed
     190 *  when an sub-observerable dies we usually don't need to do anything
     191 *  \param *publisher Sub-Observable.
     192 */
    147193void Observable::subjectKilled(Observable *publisher){
    148194}
    149195
     196/** Constructor for class Observable.
     197 */
    150198Observable::Observable()
    151199{}
    152200
    153 // when an observable is deleted, we let all our observers know
     201/** Destructor for class Observable.
     202 * When an observable is deleted, we let all our observers know. \sa Observable::subjectKilled().
     203 */
    154204Observable::~Observable()
    155205{
     
    166216}
    167217
     218/** Constructor for class Observer.
     219 */
    168220Observer::Observer()
    169221{}
    170222
     223/** Destructor for class Observer.
     224 */
    171225Observer::~Observer()
    172226{}
  • src/Patterns/Observer.hpp

    r9b6b2f rc296c2  
    1616 *
    1717 * Observers register themselves with the observables to be notified when something changes.
    18  * In the Observable code that changes attributes should be started with OBSERVE;. This macro
     18 * In the Observable code that changes, attributes should be started with OBSERVE;. This macro
    1919 * locks the observer mechanism while changes are done. At the end of the scope in which the
    2020 * macro was placed the lock is released. When the last lock is released all changes are
Note: See TracChangeset for help on using the changeset viewer.