Обновить
12
0.5
Алексей Ткаченко @a-tk

Разработчик ПО

Отправить сообщение

А когда-то новой перспективной профессией был промт-инженер... А теперь - уборщик за промт-инженером... Что дальше? Производитель контейнеров для уборщиков за промт-инженерами?

Монолит проще и надёжнее, и нет смысла делать мелкосервисы, если не доказана их необходимость.

PS: проектирование любой системы с микросервисов очень напоминает разработку мелкой консольной утилитки на Java с написания фабрик фабрик.

Что лишь подтверждает общее в этих решениях.

Походу юмор минусующие не оценили от слова совсем...

Оно ведь закрывает 80% потребностей в интернете, разве нет? Лучше предложить им дышать 80% времени.

О, мания величия собственной персоной с двух ног ворвалась в чатик.

Я о ней и говорю.

Я про текст в статье.

Всё ещё нет

Кажется, одна ось с персистентной памятью уже была в истории.

Не везде исправили.

Перед iret не нужны ни popf (и pushf в прологе), ни sti.

Будем считать это корректным, но ad-hoc решением.

/* Берёт символ из буфера без блокировки. Возвращает -1 если пусто. */
char kbd_getchar(void)

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

Кроме алфавита есть ещё раскладка, состояние shift и caps lock и ещё немножко всякое разное.

    sti                  ; разрешить прерывания
    popfd                ; восстановить EFLAGS
    iret                 ; возврат из прерывания

Эпилог обработчика прерывания немного избыточен и даже некорректен: во-первых, при входе в прерывание флаги уже на стеке, и ещё раз пушить их нет смысла. Во-вторых, команда iret обеспечивает атомарную операцию, в которой восстанавливаются флаги и осуществляется длинный переход на сохранённый адрес возврата.

У Вас же получается разрешение прерывания до выхода из обработчика, что приводит к тому, что другой обработчик может вытеснить выполнение сразу после инструкции sti. Далее, popf всё равно восстановит флаг прерываний, ранее сохранённый, поэтому операция sti перед popf тут избыточна.

// Exception с InnerException, и AggregateException с InnerExceptions есть из коробки

// по этому поводу допустим..
public class EInOutError : Exception
{
  public required int ErrorCode { get; init; }
}

try
{
  DoSomething();
}
catch (Exception ex) when (ex.HasErrorCode(200) is {} e)
{
  // Handle e
}

Для поддержки нужен один мелкий хелпер, который иерархию развернёт в плоскую коллекцию:

Текст хелпера
public static class ExceptionExtension
{
  public static EInOutError? HasErrorCode(this Exception e, int code)
  {
      return e.WithNested().OfType<EInOutError>().FirstOrDefault(x => x.ErrorCode == code);
  }
  
  public static IEnumerable<Exception> WithNested(this Exception e)
  {
    yield return e;
    
    if (e is AggregateException { InnerExceptions: { Count: > 0 } innerExceptions })
    {
      foreach (var x in innerExceptions)
      {
        yield return x;
      }
    }

    if (e.InnerException is { } inner)
    {
      yield return inner;
    }
  }
}

Информация

В рейтинге
2 066-й
Откуда
Минск, Минская обл., Беларусь
Дата рождения
Зарегистрирован
Активность

Специализация

Software Developer, Software Architect
Lead
От 1 000 000 $
C#
.NET
C++
Git