Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет yigal_s ([info]yigal_s)
@ 2011-09-17 23:27:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
академическое
Вот чего я не пойму никак - это как правильно делать выгрузку модулей в системе вроде DCOM.

Там имеется такой забавный race-condintion, что когда модуль решает, что все его объекты уничтожены и его можно выгружать, это решение принимается в коде самого модуля, так что, приняв подобное решение, код может не успеть покинуть модуль, как модуль уже будет выгружен системным тредом, успевшим черезчур быстро прочитать состояние "все объекты уничтожены", что приведет к крэшу. Классику эту еще Don Box описывал.

Можно, конечно, ввести некий протокол, обязывающий уже вызывающий код менять состояние модуля, скажем, декрементируя некоторую переменную, адрес которой он может узнать, запросив модуль. Т.е. вместо того, чтобы вести учет ссылок внутри модуля, можно обязать делать это вызывающий код. На С++ подобное можно вообще завернуть в то, что методы модуля могут возвращать некие объекты, которые, деструктурируясь, модифицирут состояние модуля, причем код модификаторов забит в .h файлы, т.е. заведомо влинковывается в код вызывающего клиента. Я, впрочем, не уверен, что стандарт С++ гарантирует, что код из .h заведомо влинкуется или заинлайнится в код клиента.

Можно, наверное, еще и умудриться перед возвратом из функции модуля, прыгнуть на некоторую библиотечную фунцию системы, которая продекрементирует счетчик, а потом уж вернетсяв код клиента. Этакий жесткий ассемблерный трюк, но может быть кто-то решит, что он заслуживает имплементации в языке? Что-то вроде оптимизации хвостовой рекурсии, только оптимизируется тут не рекурсия, а вызов последней функции. Там, впрочем, будут свои сложности, вроде того, что последний объект в системе может уничтожиться не в функции, вызванной напрямую из клиента, но вызванной из другой функции модуля, но с этой проблемой можно и побороться, она не сложна.

Оба решения, впрочем, представляются какими-то уродливыми, натужными. А вот нормального решения, про которое можно сказать "именно так и надо это решать" что-то пока не видно.

Т.е. выходит, что эту проблему я уже лет 12 не знаю как решать. С тех пор, как с ней познакомился. Позорная ситуация, вообще-то.


(Добавить комментарий)


[info]dumalkin@lj
2011-09-18 18:03 (ссылка)
У нас это организовано по таймаутам - после решения о выгрузке модуль переходит в состояние ghost, в котором находится некое конфигурируемое время.
Попытка обращения к модулю в этом состоянии приводит ре-инициализации новой инстанции модуля (тоже самое что произойдет при обращении к модулю после его окончательной выгрузки), и перенаправлению вызова туда.
После истечения ghost period модуль тихо-мирно самоудаляется.

(Ответить) (Ветвь дискуссии)


[info]yigal_s@lj
2011-09-18 18:17 (ссылка)
не, никаких таймаутов. (в DCOM, кстати их тоже сделали).

Ну разве что таймаут превышает время эксплуатации системы пользователем. Скажем, таймаут в 15 лет меня удовлетворит.

Меня интересует академическое 100% решение вопроса.

(Ответить) (Уровень выше)


[info]yigal_s@lj
2011-09-18 18:20 (ссылка)
кстати, в вашем варианте, похоже, race condition может показать реальный зубки - если кто-то попытается использовать модуль сразу после того, как он перешел в состояние ghost, это приведет к его выгрузке с известными рисками.

(Ответить) (Уровень выше)