diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2014-06-17 17:10:24 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-06-17 17:10:24 +0400 |
commit | 861ea516ec07b9a67567c439a6a4077d8a4fd518 (patch) | |
tree | a878ca97edc3ab76e551ad49d41e8985be3b8840 | |
parent | 5aec348d39d5511e1baa9627c433e7d484ab3100 (diff) | |
download | accel-ppp-861ea516ec07b9a67567c439a6a4077d8a4fd518.tar.gz accel-ppp-861ea516ec07b9a67567c439a6a4077d8a4fd518.zip |
log_file: fixed early message free
-rw-r--r-- | accel-pppd/logs/log_file.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/accel-pppd/logs/log_file.c b/accel-pppd/logs/log_file.c index 9dc88630..c759c32e 100644 --- a/accel-pppd/logs/log_file.c +++ b/accel-pppd/logs/log_file.c @@ -96,6 +96,17 @@ static int log_file_open(struct log_file_t *lf, const char *fname) return 0; } +static void purge(struct list_head *list) +{ + struct log_msg_t *msg; + + while (!list_empty(list)) { + msg = list_first_entry(list, typeof(*msg), entry); + list_del(&msg->entry); + log_free_msg(msg); + } +} + static void *log_thread(void *unused) { struct log_file_t *lf; @@ -103,6 +114,8 @@ static void *log_thread(void *unused) struct log_chunk_t *chunk; struct log_msg_t *msg; int iov_cnt; + LIST_HEAD(msg_list); + LIST_HEAD(free_list); while (1) { pthread_mutex_lock(&lock); @@ -123,8 +136,10 @@ static void *log_thread(void *unused) spin_lock(&lf->lock); if (list_empty(&lf->msgs)) { - if (iov_cnt) + if (iov_cnt) { writev(lf->fd, iov, iov_cnt); + purge(&free_list); + } lf->queued = 0; if (lf->need_free) { @@ -139,27 +154,32 @@ static void *log_thread(void *unused) break; } - msg = list_first_entry(&lf->msgs, typeof(*msg), entry); - list_del(&msg->entry); + list_splice_init(&lf->msgs, &msg_list); spin_unlock(&lf->lock); + + while (!list_empty(&msg_list)) { + msg = list_first_entry(&msg_list, typeof(*msg), entry); - iov[iov_cnt].iov_base = msg->hdr->msg; - iov[iov_cnt].iov_len = msg->hdr->len; - if (++iov_cnt == IOV_MAX) { - writev(lf->fd, iov, iov_cnt); - iov_cnt = 0; - } - - list_for_each_entry(chunk, msg->chunks, entry) { - iov[iov_cnt].iov_base = chunk->msg; - iov[iov_cnt].iov_len = chunk->len; + iov[iov_cnt].iov_base = msg->hdr->msg; + iov[iov_cnt].iov_len = msg->hdr->len; if (++iov_cnt == IOV_MAX) { writev(lf->fd, iov, iov_cnt); + purge(&free_list); iov_cnt = 0; } + + list_for_each_entry(chunk, msg->chunks, entry) { + iov[iov_cnt].iov_base = chunk->msg; + iov[iov_cnt].iov_len = chunk->len; + if (++iov_cnt == IOV_MAX) { + writev(lf->fd, iov, iov_cnt); + iov_cnt = 0; + purge(&free_list); + } + } + + list_move_tail(&msg->entry, &free_list); } - - log_free_msg(msg); } } |