OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 19 Март, 2024 08:39

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Воскресенье, 04 Сентябрь, 2016 12:18 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Почитал документацию повнимательней по Kernel.
Вот этим ребятам большущее спасибо:
Цитата:
Составитель: Ермаков И.Е.
Исправления и дополнения: Ильин А.С.

Kernel, хоть и рисковый модуль, подкинутым дятлом можно что-нибудь покалечить, но он платформо-независим.

Итак
Есть в типе Module отличное поле: refcnt- -- хранит количество ссылок на модуль!!! То, что доктор прописал!!!))
Есть там ссылка на то, что с абстрактными типами может быть бяка, если модуль реализации инсталлирует свою фабрику(sic!!!) в абстрактный тип, и при этом модуль реализации не импортируется никаким модулем. Выгрузка такого модуля реализации будет фатальной. (* кто-нибудь, если сталкивались, приведите пример такой инсталляции... Я с трудом себе представляю, как можно влезть в готовый модуль, и что-то там инсталлировать... Речь идёт о декораторе? *)
(* это, видимо, та причина, по которой я задним числом подозревал, что с динамическим созданием объектов надо поаккуратней. Вирт, на сколько помню, тоже тут осторожничает *)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Воскресенье, 04 Сентябрь, 2016 18:18 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Ну что, коллеги?)))
Работа топорная, прошу не пинать ногами. Но работает)

Некоторые пояснения: модуль должен вызываться через Dialog.Call, а не прямым обращением, так как тот модуль, который вызвал _напрямую_ модуль выгрузки -- будет ожидать возврата из процедуры в модуле выгрузки, и естественно, не позволит по цепочке выгружать модули. Здесь я не контролирую количество ссылок на модули, так как знаю, как эти модули импортируются. Ну, и стоит упомянуть отдельно -- в соответствии с документацией по Kernel -- если модуля нет в памяти, то он загружается при попытке получить указатель на него. Т.е. немного лишнего времени может быть потрачено, но безопасный результат что что-то будет выгружено -- будет точно)))

Код:
MODULE ОикЗакрытие;
   (* модуль обеспечивает выгрузку всех модулей, как внешняя команда *)

   IMPORT мЯдро := Kernel,
      мСерв := Services,
      мЛог := StdLog;

   TYPE
      тМодуль = ARRAY 50 OF CHAR;
      
      туДейств = POINTER TO RECORD (мСерв.Action)
      END;

   VAR
      список: POINTER TO ARRAY OF тМодуль;
      счёт: INTEGER;
      модуль: мЯдро.Module;
      действ: туДейств;

   PROCEDURE Модуль_Выгрузить (VAR мод_: тМодуль);
   BEGIN
      IF (мод_ # "") THEN
         модуль := мЯдро.ThisMod(мод_);
         мЯдро.UnloadMod(модуль)
      END;
   END Модуль_Выгрузить;

   PROCEDURE (сам: туДейств)Do;
      VAR
         i: INTEGER;
   BEGIN
      FOR i := 0 TO счёт DO
         Модуль_Выгрузить(список[i]);
      END;
   END Do;

   PROCEDURE Выгрузить*;
      VAR
         итер: INTEGER;
   BEGIN
      мСерв.DoLater(действ, мСерв.Ticks() + мСерв.resolution DIV 5);
      мЛог.String('  [выгрузка модулей]'); мЛог.Ln
   END Выгрузить;

   PROCEDURE Модуль_Добавить (IN мод_: ARRAY OF CHAR);
      VAR
         i: INTEGER;
   BEGIN
      FOR i := 0 TO LEN(мод_) - 1 DO
         список[счёт][i] := мод_[i]
      END;
      INC(счёт)
   END Модуль_Добавить;

BEGIN
   NEW(действ);
   NEW(список, 100);

   Модуль_Добавить("ОикГлавный");
   Модуль_Добавить("ОикПланировщик");
   Модуль_Добавить("ГипОкно_охрана");
END ОикЗакрытие.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Воскресенье, 04 Сентябрь, 2016 18:45 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Чтобы лишние модули у тебя не загружались, лучше используй ThisLoadedMod как в DevDebug
Код:
   PROCEDURE UnloadMod (name: TextMappers.String; VAR ok: BOOLEAN);
      VAR mod: Kernel.Module; str: Dialog.String;
   BEGIN
      mod := Kernel.ThisLoadedMod(name);
      IF mod # NIL THEN
         IF name # "DevDebug" THEN
            Dialog.ShowParamStatus("#Dev:Unloading", name, "", "");
            Kernel.UnloadMod(mod)
         END;
         IF mod.refcnt < 0 THEN
            Dialog.MapParamString("#Dev:Unloaded", name, "", "", str);
            StdLog.String(str); StdLog.Ln
         ELSE
            Dialog.ShowParamMsg("#Dev:UnloadingFailed", name, "", "");
            ok := FALSE
         END
      ELSE
         Dialog.ShowParamMsg("#Dev:NotFound", name, "", "");
         ok := FALSE;
      END
   END UnloadMod;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Воскресенье, 04 Сентябрь, 2016 19:17 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 473
Откуда: KZ
prospero78 писал(а):
...
Код:
...
   PROCEDURE (сам: туДейств)Do;
      VAR
         i: INTEGER;
   BEGIN
      FOR i := 0 TO счёт DO
         Модуль_Выгрузить(список[i]);
      END;
   END Do;
...
...

счёт - 1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Воскресенье, 04 Сентябрь, 2016 19:33 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Это вряд ли -- счёт (-1).
Так как массив индексируется с нуля. Индекс цикла и индекс массива точно совпадают.
Все 220 модулей успешно выгружаются.
Кроме того, который выгружает сам все остальные. Но, он не имеет импортов -- перекомпиляция и выгрузка происходит легко.
С тупо висящими 3762 байтами я готов смириться)))

Ваня, подсказка про ThisLoadedMod -- существенная!!)) Благодарю, пользую))
Но лишние модули и так выгрузка не загружает. Всё что выгружает -- всё пользуется, всё в памяти.
Но если, например, модуль верхнего уровня необходимо выгрузить ,а его нет -- он сначала загрузит все нижележащие)))
А это уже некрасиво в моём варианте))

При запуске -- 1,67 МБ.
При загруженной программе дорасчёта -- 5,42 МБ.
После отработки выгрузки -- 1,65 МБ.

В-общем, тему можно закрывать. (* содержание несколько не соответствует топику, но мой вариант, по моему, на этом форуме -- первое практическое решение))) *)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Понедельник, 05 Сентябрь, 2016 21:46 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
А чем не нравятся DevDebug.Unload и DevDebug.UnloadThis ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Вторник, 06 Сентябрь, 2016 09:50 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Тем, что требуется выделение текста в одном случае, и открытый текст исходного кода в фокусе при другой функции.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Вторник, 06 Сентябрь, 2016 11:49 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
prospero78 писал(а):
Тем, что требуется выделение текста в одном случае, и открытый текст исходного кода в фокусе при другой функции.

Ну вообще то не требуется, UnloadThis выгружает список модулей указанный после себя.
Но то, что ты сделал - удобно, если вообще не открыт графический интерфейс, например, - в серверном приложении. Хочешь ты, чтобы сервер подцепил новые модули, посылаешь команду на выгрузку, планируется выгрузка, и потом в подходящий момент запускается вот такой, например, как у тебя механизм.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Вторник, 06 Сентябрь, 2016 12:24 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
По упомянутой команде получалось через раз. Видимо, я что-то делаю не так.

Ты читаешь мои мысли. Я как никогда близок к реализации идеи -- "машина, которая сама себе на ходу меняет колёса". Шину сообщений создать под это дело, либо выделить протокол в существующей шине -- это вообще не проблема. Хоть удалённый сервер, хоть локальный, хоть сервер в том же самом процессе))
Алгоритм:
1. Заморозить состояние объекта.
2. Выгрузить модуль-обработчик (старая версия)
3. Скомпилировать модуль-обработчик (новая версия)
4. Загрузить модуль-обработчик (новая версия)
5. Разморозить объект.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Вторник, 06 Сентябрь, 2016 18:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
prospero78 писал(а):
Ты читаешь мои мысли.

Потому, что я подобной штукой пользуюсь в своем расширении Robust.

Там только один ББ запускается с GUI, а остальные это вычислительные сервера. И когда я в GUI подготовил новый вариант модуля, то хочу, чтобы сервера его тоже перезагрузили. Посылаю сервисное сообщение. Но у меня задачи попроще, видимо, поэтому выгружаю модули по одному и в четком порядке по очереди.
Код:
PROCEDURE (msg: ServiceMsg) Processor;
   VAR mod: Kernel.Module;
   BEGIN
      CASE msg.command OF 1:
         LogMsg("Get exit message");
         Kernel.Quit(0);
      | 2:
         IF (msg.comment$ # 'Init') & (msg.comment$ # 'Kernel') THEN
            mod := Kernel.ThisLoadedMod(SHORT(msg.comment$));
            IF mod # NIL THEN
               Kernel.UnloadMod(mod);
               LogMsg("Module: " + msg.comment$ + " unloaded.")
            ELSE
               LogMsg("Module: " + msg.comment$ + " is not loaded.")
            END
         ELSE
            LogMsg("server: could not unload essential module.")
         END
      ELSE
         LogMsg("Get unknown command with service message.");
      END
   END Processor;


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB