summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-06-17 17:10:24 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-06-17 17:10:24 +0400
commit861ea516ec07b9a67567c439a6a4077d8a4fd518 (patch)
treea878ca97edc3ab76e551ad49d41e8985be3b8840
parent5aec348d39d5511e1baa9627c433e7d484ab3100 (diff)
downloadaccel-ppp-861ea516ec07b9a67567c439a6a4077d8a4fd518.tar.gz
accel-ppp-861ea516ec07b9a67567c439a6a4077d8a4fd518.zip
log_file: fixed early message free
-rw-r--r--accel-pppd/logs/log_file.c50
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);
}
}