ObservableHandler::~ObservableHandler() { if(CountTargets()) { PRINT(( "*** ~ObservableHandler() '%s': %" B_PRId32 " observers remain\n", Name(), CountTargets())); } }
ObservableLooper::~ObservableLooper() { if(CountTargets()) { PRINT(( "*** ~ObservableLooper() '%s': %ld observers remain\n", Name(), CountTargets())); } if(m_executioner) delete m_executioner; }
bool ObservableLooper::QuitRequested() { if(CountTargets()) { if(!m_quitting) { m_quitting = true; // no release request yet sent notifyRelease(); if(m_quitTimeout != B_INFINITE_TIMEOUT) { // Initiate a timer to force quit -- if an observer // has died, it shouldn't take me down with it. ASSERT(!m_executioner); m_executioner = new BMessageRunner( BMessenger(this), new BMessage(M_KILL_OBSERVABLE), m_quitTimeout, 1); } } // targets remain, so don't quit. return false; } // okay to quit return true; }
void ObservableLooper::_handleRemoveObserver( BMessage* message) { // PRINT(("ObservableLooper::_handleRemoveObserver():\n" // " %ld targets\n", CountTargets())); BMessage reply; BMessenger observer; status_t err = message->FindMessenger( "observer", &observer); if(err < B_OK) { PRINT(( "* ObservableLooper::_handleRemoveObserver(): no observer specified!\n")); // send reply? +++++ return; } // at this point, a reply of some sort will be sent reply.AddMessenger("target", BMessenger(this)); reply.AddMessenger("observer", observer); int32 index = IndexOfTarget(observer.Target(0)); if(index == -1) { reply.what = M_BAD_OBSERVER; } else { RemoveTarget(index); reply.what = M_OBSERVER_REMOVED; } message->SendReply(&reply); // call hook observerRemoved(observer); // time to shut down? if(m_quitting && !CountTargets()) { releaseComplete(); BLooper::Quit(); } }
void ObservableHandler::_handleRemoveObserver( BMessage* message) { #if DEBUG BLooper* l = Looper(); ASSERT(l); ASSERT(l->IsLocked()); #endif BMessage reply; BMessenger observer; status_t err = message->FindMessenger( "observer", &observer); if(err < B_OK) { PRINT(( "* ObservableHandler::_handleRemoveObserver(): no observer specified!\n")); // send reply? +++++ return; } int32 index = IndexOfTarget(observer.Target(0)); if(index == -1) { reply.what = M_BAD_OBSERVER; reply.AddMessenger("target", BMessenger(this)); reply.AddMessenger("observer", observer); message->SendReply(&reply); return; } // valid observer given; remove it & call notification hook RemoveTarget(index); observerRemoved(observer); // time to shut down? if(m_released && !CountTargets()) { releaseComplete(); delete this; // BOOM! } }
__USE_CORTEX_NAMESPACE // ---------------------------------------------------------------- // // *** deletion // ---------------------------------------------------------------- // // clients must call release() rather than deleting, // to ensure that all observers are notified of the // object's demise. if the object has already been // released, return an error. status_t ObservableHandler::release() { if(m_released) return B_NOT_ALLOWED; // PRINT(( // "ObservableHandler::release(): %ld targets\n", CountTargets())); if(!LockLooper()) { ASSERT(!"failed to lock looper"); } m_released = true; if(CountTargets()) { // notify notifyRelease(); UnlockLooper(); } else { releaseComplete(); UnlockLooper(); delete this; } return B_OK; }