Может ли системный вызов быть программно прерван? - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь написать модульный тест для моего приложения ZeroMQ (которое я использую через слой cppzmq C ++). Моя проблема в том, что когда я пытаюсь закрыть свой контекст, это иногда (на первый взгляд случайно) дает сбой. Я не знаю, почему именно, за исключением того, что код ошибки установлен в EINTR, что означает прерванный системный вызов.

Чтобы написать (провальный) модульный тест для этого поведения (который я могу затем попытаться исправить), я подумал ( см. Также этот PR ), было бы полезно, если бы я мог каким-то образом подделать эти системы. звонки, которые прерываются. Внутри этого поддельного системного вызова я могу сначала просто вызвать обычный системный вызов, но затем перед возвратом вручную установить код ошибки в EINTR. Например, я хотел бы заменить recv на что-то вроде:

ssize_t recv(int sockfd, void *buf, size_t len, int flags) {
    ssize_t result = ::recv(sockfd, buf, len, flags);
    errno = EINTR;
    return result;
}

Возможно ли это? Разумно ли это (можно ли ожидать проблем и если да, то какие)? Есть ли другой способ решить мою проблему с модульным тестированием?

1 Ответ

0 голосов
/ 02 ноября 2018

EINTR возвращается при получении правильно настроенного прерывания во время блокирующего системного вызова.

Вероятно, самый простой сигнал для поднятия - это SIGALRM, который можно запланировать, просто вызвав:

alarm(1);
recv(...);

И через секунду вы получите SIGALRM.

Если вы не хотите ждать 1 секунду, вы можете получить точность до секунды с помощью setitimer().

...