dcavalca / rpms / systemd

Forked from rpms/systemd 4 months ago
Clone
Zbigniew Jędrzejewski-Szmek 399a2a
From 706ce3faab879d4cb20906ad6d27e962ab3e4ad0 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 399a2a
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek 399a2a
Date: Fri, 13 Mar 2015 00:02:28 -0400
Zbigniew Jędrzejewski-Szmek 399a2a
Subject: [PATCH] journal-remote: process events without delay
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
journal-remote buffers input, and then parses it handling one journal entry at a time.
Zbigniew Jędrzejewski-Szmek 399a2a
It was possible for useful data to be left in the buffer after some entries were
Zbigniew Jędrzejewski-Szmek 399a2a
processesed. But all data would be already read from the fd, so there would be
Zbigniew Jędrzejewski-Szmek 399a2a
no reason for the event loop to call the handler again. After some new data came in,
Zbigniew Jędrzejewski-Szmek 399a2a
the handler would be called again, and would then process the "old" data in the buffer.
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
Fix this by enabling a handler wherever we process input data and do not exhaust data
Zbigniew Jędrzejewski-Szmek 399a2a
from the input buffer (i.e. when EAGAIN was not encountered). The handler runs until
Zbigniew Jędrzejewski-Szmek 399a2a
we encounter EAGAIN.
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
Looping over the input data is done in this roundabout way to allow the event loop
Zbigniew Jędrzejewski-Szmek 399a2a
to dispatch other events in the meanwhile. If the loop was inside the handler, a
Zbigniew Jędrzejewski-Szmek 399a2a
source which produced data fast enough could completely monopolize the process.
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
https://bugs.freedesktop.org/show_bug.cgi?id=89516
Zbigniew Jędrzejewski-Szmek 399a2a
(cherry picked from commit 043945b93824e33e040954612aaa934cd1a43a1b)
Zbigniew Jędrzejewski-Szmek 399a2a
---
Zbigniew Jędrzejewski-Szmek 399a2a
 src/journal-remote/journal-remote-parse.c |  1 +
Zbigniew Jędrzejewski-Szmek 399a2a
 src/journal-remote/journal-remote-parse.h |  1 +
Zbigniew Jędrzejewski-Szmek 399a2a
 src/journal-remote/journal-remote.c       | 65 +++++++++++++++++++++++++++----
Zbigniew Jędrzejewski-Szmek 399a2a
 3 files changed, 59 insertions(+), 8 deletions(-)
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
Zbigniew Jędrzejewski-Szmek 399a2a
index 6c096de03a..7e62954351 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/journal-remote/journal-remote-parse.c
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/journal-remote/journal-remote-parse.c
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -41,6 +41,7 @@ void source_free(RemoteSource *source) {
Zbigniew Jędrzejewski-Szmek 399a2a
         writer_unref(source->writer);
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         sd_event_source_unref(source->event);
Zbigniew Jędrzejewski-Szmek 399a2a
+        sd_event_source_unref(source->buffer_event);
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         free(source);
Zbigniew Jędrzejewski-Szmek 399a2a
 }
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/journal-remote/journal-remote-parse.h b/src/journal-remote/journal-remote-parse.h
Zbigniew Jędrzejewski-Szmek 399a2a
index 22db550913..06a50296a1 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/journal-remote/journal-remote-parse.h
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/journal-remote/journal-remote-parse.h
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -54,6 +54,7 @@ typedef struct RemoteSource {
Zbigniew Jędrzejewski-Szmek 399a2a
         Writer *writer;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         sd_event_source *event;
Zbigniew Jędrzejewski-Szmek 399a2a
+        sd_event_source *buffer_event;
Zbigniew Jędrzejewski-Szmek 399a2a
 } RemoteSource;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
 RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer);
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
Zbigniew Jędrzejewski-Szmek 399a2a
index d1486e7cda..b7cc6d7172 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/journal-remote/journal-remote.c
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/journal-remote/journal-remote.c
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -289,6 +289,8 @@ static int dispatch_raw_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
                                      int fd,
Zbigniew Jędrzejewski-Szmek 399a2a
                                      uint32_t revents,
Zbigniew Jędrzejewski-Szmek 399a2a
                                      void *userdata);
Zbigniew Jędrzejewski-Szmek 399a2a
+static int dispatch_raw_source_until_block(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                           void *userdata);
Zbigniew Jędrzejewski-Szmek 399a2a
 static int dispatch_blocking_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
                                           void *userdata);
Zbigniew Jędrzejewski-Szmek 399a2a
 static int dispatch_raw_connection_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -376,8 +378,15 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         r = sd_event_add_io(s->events, &source->event,
Zbigniew Jędrzejewski-Szmek 399a2a
                             fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI,
Zbigniew Jędrzejewski-Szmek 399a2a
-                            dispatch_raw_source_event, s);
Zbigniew Jędrzejewski-Szmek 399a2a
-        if (r == -EPERM) {
Zbigniew Jędrzejewski-Szmek 399a2a
+                            dispatch_raw_source_event, source);
Zbigniew Jędrzejewski-Szmek 399a2a
+        if (r == 0) {
Zbigniew Jędrzejewski-Szmek 399a2a
+                /* Add additional source for buffer processing. It will be
Zbigniew Jędrzejewski-Szmek 399a2a
+                 * enabled later. */
Zbigniew Jędrzejewski-Szmek 399a2a
+                r = sd_event_add_defer(s->events, &source->buffer_event,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                       dispatch_raw_source_until_block, source);
Zbigniew Jędrzejewski-Szmek 399a2a
+                if (r == 0)
Zbigniew Jędrzejewski-Szmek 399a2a
+                        sd_event_source_set_enabled(source->buffer_event, SD_EVENT_OFF);
Zbigniew Jędrzejewski-Szmek 399a2a
+        } else if (r == -EPERM) {
Zbigniew Jędrzejewski-Szmek 399a2a
                 log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name);
Zbigniew Jędrzejewski-Szmek 399a2a
                 r = sd_event_add_defer(s->events, &source->event,
Zbigniew Jędrzejewski-Szmek 399a2a
                                        dispatch_blocking_source_event, source);
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -997,15 +1006,18 @@ static void server_destroy(RemoteServer *s) {
Zbigniew Jędrzejewski-Szmek 399a2a
  **********************************************************************
Zbigniew Jędrzejewski-Szmek 399a2a
  **********************************************************************/
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
-static int dispatch_raw_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
-                                     int fd,
Zbigniew Jędrzejewski-Szmek 399a2a
-                                     uint32_t revents,
Zbigniew Jędrzejewski-Szmek 399a2a
-                                     void *userdata) {
Zbigniew Jędrzejewski-Szmek 399a2a
+static int handle_raw_source(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
+                             int fd,
Zbigniew Jędrzejewski-Szmek 399a2a
+                             uint32_t revents,
Zbigniew Jędrzejewski-Szmek 399a2a
+                             RemoteServer *s) {
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
-        RemoteServer *s = userdata;
Zbigniew Jędrzejewski-Szmek 399a2a
         RemoteSource *source;
Zbigniew Jędrzejewski-Szmek 399a2a
         int r;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
+        /* Returns 1 if there might be more data pending,
Zbigniew Jędrzejewski-Szmek 399a2a
+         * 0 if data is currently exhausted, negative on error.
Zbigniew Jędrzejewski-Szmek 399a2a
+         */
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
         assert(fd >= 0 && fd < (ssize_t) s->sources_size);
Zbigniew Jędrzejewski-Szmek 399a2a
         source = s->sources[fd];
Zbigniew Jędrzejewski-Szmek 399a2a
         assert(source->fd == fd);
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -1036,11 +1048,48 @@ static int dispatch_raw_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
                 return 1;
Zbigniew Jędrzejewski-Szmek 399a2a
 }
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
+static int dispatch_raw_source_until_block(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                           void *userdata) {
Zbigniew Jędrzejewski-Szmek 399a2a
+        RemoteSource *source = userdata;
Zbigniew Jędrzejewski-Szmek 399a2a
+        int r;
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        /* Make sure event stays around even if source is destroyed */
Zbigniew Jędrzejewski-Szmek 399a2a
+        sd_event_source_ref(event);
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        r = handle_raw_source(event, source->fd, EPOLLIN, server);
Zbigniew Jędrzejewski-Szmek 399a2a
+        if (r != 1)
Zbigniew Jędrzejewski-Szmek 399a2a
+                /* No more data for now */
Zbigniew Jędrzejewski-Szmek 399a2a
+                sd_event_source_set_enabled(event, SD_EVENT_OFF);
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        sd_event_source_unref(event);
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        return r;
Zbigniew Jędrzejewski-Szmek 399a2a
+}
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+static int dispatch_raw_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                     int fd,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                     uint32_t revents,
Zbigniew Jędrzejewski-Szmek 399a2a
+                                     void *userdata) {
Zbigniew Jędrzejewski-Szmek 399a2a
+        RemoteSource *source = userdata;
Zbigniew Jędrzejewski-Szmek 399a2a
+        int r;
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        assert(source->event);
Zbigniew Jędrzejewski-Szmek 399a2a
+        assert(source->buffer_event);
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        r = handle_raw_source(event, fd, EPOLLIN, server);
Zbigniew Jędrzejewski-Szmek 399a2a
+        if (r == 1)
Zbigniew Jędrzejewski-Szmek 399a2a
+                /* Might have more data. We need to rerun the handler
Zbigniew Jędrzejewski-Szmek 399a2a
+                 * until we are sure the buffer is exhausted. */
Zbigniew Jędrzejewski-Szmek 399a2a
+                sd_event_source_set_enabled(source->buffer_event, SD_EVENT_ON);
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
+        return r;
Zbigniew Jędrzejewski-Szmek 399a2a
+}
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
 static int dispatch_blocking_source_event(sd_event_source *event,
Zbigniew Jędrzejewski-Szmek 399a2a
                                           void *userdata) {
Zbigniew Jędrzejewski-Szmek 399a2a
         RemoteSource *source = userdata;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
-        return dispatch_raw_source_event(event, source->fd, EPOLLIN, server);
Zbigniew Jędrzejewski-Szmek 399a2a
+        return handle_raw_source(event, source->fd, EPOLLIN, server);
Zbigniew Jędrzejewski-Szmek 399a2a
 }
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
 static int accept_connection(const char* type, int fd,