Хорошо, наконец-то я нашел решение.
Суть моей проблемы заключалась в многопоточности моего сервера.После долгих поисков я обнаружил, что в случае, если у нас есть сигналы, полученные от другого процесса (асинхронно), не имеет значения, какой сигнал захвата потока, потому что поведение остается тем же: сигнал перехватывается, а ранее зарегистрированный обработчикказнены.Возможно, это могло быть очевидно для других, но это сводило меня с ума, потому что я не знал, как интерпретировать ошибки, которые возникали во время выполнения.
После этого я обнаружил другую проблему, которую решил, о устаревшем вызове signal()
.Во время выполнения, когда я в первый раз поднимаюсь на SIGUSR1
, программа ловит и управляет ею, как и ожидалось, но во второй раз она завершается с User defined signal 1
.
. Я выяснил, что signal()
вызов установлен «один раз».обработчик для конкретного сигнала, после первой обработки сигнала поведение этого сигнала возвращает значение по умолчанию.
Итак, вот что я сделал:
Вот обработчики сигнала:
Примечание: я сбрасываю обработчик для SIGUSR1
внутри самого обработчика
static void on_SIGINT(int signum)
{
if(signum == SIGINT || signum == SIGTERM)
serverStop = TRUE;
}
static void on_SIGUSR1(int signum)
{
if(signum == SIGUSR1)
pendingSIGUSR1 = TRUE;
if(signal(SIGUSR1, &on_SIGUSR1) == SIG_ERR)
exit(EXIT_FAILURE);
}
Здесь я устанавливаю обработчики во время инициализации сервера:
if(signal(SIGINT, &on_SIGINT) == SIG_ERR)
exit(EXIT_FAILURE);
if(signal(SIGTERM, &on_SIGINT) == SIG_ERR)
exit(EXIT_FAILURE);
if(signal(SIGUSR1, &on_SIGUSR1) == SIG_ERR)
exit(EXIT_FAILURE);
if(signal(SIGPIPE, SIG_IGN) == SIG_ERR)
exit(EXIT_FAILURE);
А вот цикл прослушивания сервера:
while(!serverStop)
{
if (pendingSIGUSR1)
{
... things i have to do on SIGUSR1...
pendingSIGUSR1 = FALSE;
}
test = saveSet(masterSet, &backUpSet, &saveMaxFd);
CHECK_MINUS1(test, "Server: creating master set's backup ");
int test = select(saveMaxFd+1, &backUpSet, NULL, NULL, &waiting);
if((test == -1 && errno == EINTR) || test == 0)
continue;
if (test == -1 && errno != EINTR)
{
perror("Server: Monitoring sockets: ");
exit(EXIT_FAILURE);
}
for(int sock=3; sock <= saveMaxFd; sock++)
{
if (FD_ISSET(sock, &backUpSet))
{
if(sock == ConnectionSocket)
{
ClientSocket = accept(ConnectionSocket, NULL, 0);
CHECK_MINUS1(ClientSocket, "Server: Accepting connection");
test = INset(masterSet, ClientSocket);
CHECK_MINUS1(test, "Server: Inserting new connection in master set: ");
}
else
{
test = OUTset(masterSet, sock);
CHECK_MINUS1(test, "Server: Removing file descriptor from select ");
test = insertRequest(chain, sock);
CHECK_MINUS1(test, "Server: Inserting request in chain");
}
}
}
}