so_4: Версия 4.2.7. Динамическая кооперация для Qt-агентов
Qt v.3.* требует, чтобы все объекты, производные от QObject (в частности все QWidget-ы) работали только на главной нити приложения. Это касается как собственно работы объектов, так и их уничтожения. Если агент является производным от QObject, то эти правила должны распространяться и на него. Для того, чтобы агент-qt-widget работал на контексте главной нити предназначен диспетчер главной нити для Qt (см.
so_4::disp::qt_ui::create_disp(),
so_4::disp::qt_ui::query_gui_thread_traits()). Но уничтожение таких агентов до версии 4.2.7 выполнялось обычным образом: SObjectizer на контексте одной из своих нитей определял, что кооперация с агентом-qt-widget может быть дерегистрирована, после чего выполнял на этой же нити действия по дерегистрации. Если агент-qt-widget был создан динамически, то он уничтожался так же на контексте этой нити. Что при некоторых обстоятельствах приводило к краху приложения (т.к. Qt еще считал, что widget существует и пытался передать ему на обработку очередные GUI-события).
Для решения данной проблемы в версии 4.2.7 добавлен класс
so_4::disp::qt_ui::dyn_coop_t, который должен использоваться для динамических коопераций с агентами-qt-widget. При дерегистрации кооперации этот класс проверяет каждого агента кооперации. Если агент унаследован от QObject, то такой агент уничтожается с помощью QObject::deleteLater. Все остальные агенты уничтожаются обычным способом.
Класс so_4::disp::qt_ui::dyn_coop_t является производным от so_4::rt::dyn_agent_coop_t и поддерживает всю функциональность последнего: