alex-ac/UniSched — Issue #26: Пересмотр модульной подсистемы
Author: alex-ac
Created: 2012-02-17 11:28:50+00:00
State: open

Пересматриваю свойства модульной подсистемы.
###### Что мы имеем сейчас:
* Класс модуля AbstractBackend;
* Класс модуля пользовательского интерфейса UI::AbstractUI (наследует AbstractBackend);
* Класс модуля базы данных (пишу сейчас) Storage::AbstractDataBase (наследует AbstractBackend);
* Свойства любого модуля:
* Должен содержать реализацию не абстрактного класса, наследующего один из вышеперечисленных классов;
* Должен содержать статический объект этого класса;
* Должен быть скомпилирован как SharedObject;
* Подключить модуль к основному исполняемому файлу его следует загрузить в тоже виртуальное адресное пространство. Сделать это можно двумя способами:
* Прилинковать модуль к raspisator на этапе сборки, тогда модуль будет загружаться вместе с самой программой;
* Загрузить модуль непосредственно перед запуском программы с помощью переменной окружения LD_PRELOAD (обращаю внимание, что данный способ не будет работать под Windows, даже если нам удастся все-таки собрать для неё бинарники, однако, помнится, аналогичный способ загрузки .dll там был, хоть и довольно не тривиальный);
* Ограничения:
* Только один модуль каждого типа может работать в каждый конкретный момент времени;
* Возможности сменить используемый модуль, не перезапуская программу (даже если он загружен в память), нет;
* Не предусмотрен способ выбора какой модуль использовать для работы, используется первый найденный подходящий;

###### Вопрос:
Стоит ли работать над снятием первых двух ограничений? О том, что надо снимать последнее, даже не спрашиваю, просто надо.

###### Как это работает.
Рассмотрим, как работает модуль класса SomeUI (унаследован от UI::AbstractUI). пусть он будет скомпилирован в libsomeui.so.

Мы запускаем программу и загружаем в её адресное пространство модуль.
$ LD_PRELOAD=libsomeui.so raspisator
Конструкторы статических объектов вызываются до вызова main(), поэтому в определенный момент времени будет вызван конструктор по умолчанию объекта класса SomeUI.
Для простоты предположим, что конструктор объекта пустой. Однако даже если он не пустой, до начала исполнения тела конструктора будет передано управление а конструктор UI::AbstractUI.
Вызывается конструктор AbstractBackend, с параметром AbstractBackend::UI, чтобы установить тип модуля.
Сам конструктор AbstractBackend добавляет указатель this на объект в статический вектор.
После конструкции всех статических объектов в этом векторе будут указатели на объекты всех загруженных модулей.