From 4aae5b0a3da47edea8a13eebe76bf33e8d5561aa Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 31 Dec 2015 13:47:03 +0100 Subject: syslogd: don't wait anymore after a stuck reader is detected If syslogd detects that the semaphore is held for too long, it will now stop waiting until the semaphore is released. This ensures that we don't risk slowing down all operations during this period. --- sysklogd/syslogd.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 4bd9b69..40f450e 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -125,6 +125,9 @@ static bool small = false; /* circular buffer variables/structures */ #ifdef CONFIG_FEATURE_IPC_SYSLOG +/* wait for one second max for the reader to release the semaphore */ +#define DEFAULT_SEMOP_WAIT 1 + #if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4 #error Sorry, you must set the syslogd buffer size to at least 4KB. #error Please check CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE @@ -171,13 +174,19 @@ static inline void sem_up(int semid) static inline int sem_down(int semid) { struct timespec timeout; + static int max_wait = DEFAULT_SEMOP_WAIT; do { - timeout.tv_sec = 1; timeout.tv_nsec = 0; - if (semtimedop(semid, SMwdn, 3, &timeout) != -1) + timeout.tv_sec = max_wait; timeout.tv_nsec = 0; + if (semtimedop(semid, SMwdn, 3, &timeout) != -1) { + /* after a success we know the reader can be trusted */ + max_wait = DEFAULT_SEMOP_WAIT; return 0; - if (errno == EAGAIN) + } + if (errno == EAGAIN) { + max_wait = 0; return -1; + } } while (errno == EINTR); bb_perror_msg_and_die("semop[SMwdn]"); return -1; -- 1.7.12.1