This source file includes following definitions.
- GetInstance
- Connect
- Disconnect
- WeakNotify
#include "ui/base/gtk/g_object_destructor_filo.h"
#include <glib-object.h>
#include "base/logging.h"
#include "base/memory/singleton.h"
namespace ui {
GObjectDestructorFILO::GObjectDestructorFILO() {
}
GObjectDestructorFILO::~GObjectDestructorFILO() {
}
GObjectDestructorFILO* GObjectDestructorFILO::GetInstance() {
return Singleton<GObjectDestructorFILO>::get();
}
void GObjectDestructorFILO::Connect(
GObject* object, DestructorHook callback, void* context) {
const Hook hook(object, callback, context);
HandlerMap::iterator iter = handler_map_.find(object);
if (iter == handler_map_.end()) {
g_object_weak_ref(object, WeakNotifyThunk, this);
handler_map_[object].push_front(hook);
} else {
iter->second.push_front(hook);
}
}
void GObjectDestructorFILO::Disconnect(
GObject* object, DestructorHook callback, void* context) {
HandlerMap::iterator iter = handler_map_.find(object);
if (iter == handler_map_.end()) {
LOG(DFATAL) << "Unable to disconnect destructor hook for object " << object
<< ": hook not found (" << callback << ", " << context << ").";
return;
}
HandlerList& dtors = iter->second;
if (dtors.empty()) {
LOG(DFATAL) << "Destructor list is empty for specified object " << object
<< " Maybe it is being executed?";
return;
}
if (!dtors.front().equal(object, callback, context)) {
DVLOG(1) << "Destructors should be unregistered the reverse order they "
<< "were registered. But for object " << object << " "
<< "deleted hook is "<< context << ", the last queued hook is "
<< dtors.front().context;
}
for (HandlerList::iterator i = dtors.begin(); i != dtors.end(); ++i) {
if (i->equal(object, callback, context)) {
dtors.erase(i);
break;
}
}
if (dtors.empty()) {
g_object_weak_unref(object, WeakNotifyThunk, this);
handler_map_.erase(iter);
}
}
void GObjectDestructorFILO::WeakNotify(GObject* where_the_object_was) {
HandlerMap::iterator iter = handler_map_.find(where_the_object_was);
DCHECK(iter != handler_map_.end());
DCHECK(!iter->second.empty());
HandlerList dtors;
iter->second.swap(dtors);
handler_map_.erase(iter);
for (HandlerList::iterator i = dtors.begin(); i != dtors.end(); ++i)
i->callback(i->context, where_the_object_was);
}
}