Раньше не имел привычки следить за тем, сколько ресурсов процессора жрут мои приложения. Теперь буду.
Сервер жрет столько ресурсов, потому что он в бесконечном цикле опрашивает наборы сокетов на готовность чтения или записи. В принципе, можно блокироваться в первом вызове select() ожидая прихода данных от клиента, поскольку, пока данные не придут, проверять набор сокетов на готовность к записи и посылать что-либо по сети бессмысленно. Это исправление я и сделал - теперь в топе top'а ни сервер, ни клиенты не показываются.
Контекстный патч для termserv/net.c:
- Код: Выделить всё
*** ../net.c 2009-08-09 20:16:29.000000000 +0400
--- net.c 2009-08-10 14:10:28.000000000 +0400
***************
*** 344,359 ****
while (1) {
rset = allset;
! memset(&tivl, 0, sizeof(tivl));
! tivl.tv_sec = 0;
! tivl.tv_usec = 0;
! if ((nready = select(maxfd + 1, &rset, NULL, NULL, &tivl)) < 0) {
syslog(LOG_ERR, "Error select(): %s\n", strerror(errno));
goto shutdown;
}
- if (nready == 0){
- goto selectwrite;
- }
/* соединение с новым клиентом */
if (FD_ISSET(lawsfd, &rset)) {
if ((connfd = accept(lawsfd, (struct sockaddr *)&cliaddr,
--- 344,353 ----
while (1) {
rset = allset;
! if ((nready = select(maxfd + 1, &rset, NULL, NULL, NULL)) < 0) {
syslog(LOG_ERR, "Error select(): %s\n", strerror(errno));
goto shutdown;
}
/* соединение с новым клиентом */
if (FD_ISSET(lawsfd, &rset)) {
if ((connfd = accept(lawsfd, (struct sockaddr *)&cliaddr,
***************
*** 459,467 ****
}
}
- selectwrite:
memset(&tivl, 0, sizeof(tivl));
! tivl.tv_sec = 0;
tivl.tv_usec = 0;
FD_ZERO(&wset);
wset = allset;
--- 453,460 ----
}
}
memset(&tivl, 0, sizeof(tivl));
! tivl.tv_sec = TIME;
tivl.tv_usec = 0;
FD_ZERO(&wset);
wset = allset;
Также заметил, что termemu не обрабатывает завершение сервера, а так и продолжает крутиться в бэкграунде. Ну тут все исправилось довольно просто - нужно обрабатывать EOF, получаемый read(), в случае закрытия другой стороны соединения.
Контекстный патч для termemu/net.c:
- Код: Выделить всё
*** ../net.c 2009-08-10 14:31:49.000000000 +0400
--- net.c 2009-08-10 18:36:34.000000000 +0400
***************
*** 170,175 ****
--- 170,177 ----
if (readretval == -1) {
syslog(LOG_ERR, "Error reading packet from socket: %s\n", strerror(errno));
goto shutdown;
+ } else if (readretval == 0) { /* сервер закрыл соединение */
+ goto shutdown;
}
/* Мы прочитали пакет до конца, не прервавшись по таймауту.
* Переходим к обработке полученного пакета
***************
*** 208,214 ****
default: /* получили то, что не должны были получить */
break;
} /* switch (incoming_pckt[0]) */
! } /* if (readretval != -2) */
/* Проверяем буфер отправки данных.
* Если он не пуст - отправляем из него данные в сеть.
--- 210,216 ----
default: /* получили то, что не должны были получить */
break;
} /* switch (incoming_pckt[0]) */
! } /* if (readretval > 0) */
/* Проверяем буфер отправки данных.
* Если он не пуст - отправляем из него данные в сеть.
Для тех, у кого отсутствует patch - архивы с termemu и termserv:
MD5 суммы:
- Код: Выделить всё
d3c01f63548fbca3998b0f2303f4fccb termemu_and_termserv.tar.gz
032521140ddc10afd74be7b39b3262ee termemu_and_termserv.zip
Университет развивает все способности, в том числе — глупость.
-- Антон Павлович Чехов