diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-11 02:09:36 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-11 23:10:40 +0200 |
commit | 2100fa1099b086411270a2876dde0532ea2806fa (patch) | |
tree | f58974c466048ba1b4f8d65017bda6b686814b9d /src/libsystemd-bus/bus-socket.c | |
parent | 9be9c7cff600018279a0c3fa5fbe719bd1c0b8ad (diff) |
bus: calculate iovec for messages only when we need it
Diffstat (limited to 'src/libsystemd-bus/bus-socket.c')
-rw-r--r-- | src/libsystemd-bus/bus-socket.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 1a0d9266f2..5e285c9e52 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -58,6 +58,39 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) { } } +static void append_iovec(sd_bus_message *m, const void *p, size_t sz) { + assert(m); + assert(p); + assert(sz > 0); + + m->iovec[m->n_iovec].iov_base = (void*) p; + m->iovec[m->n_iovec].iov_len = sz; + m->n_iovec++; +} + +static void bus_message_setup_iovec(sd_bus_message *m) { + assert(m); + assert(m->sealed); + + if (m->n_iovec > 0) + return; + + append_iovec(m, m->header, sizeof(*m->header)); + + if (m->fields) { + append_iovec(m, m->fields, m->header->fields_size); + + if (m->header->fields_size % 8 != 0) { + static const uint8_t padding[7] = {}; + + append_iovec(m, padding, 8 - (m->header->fields_size % 8)); + } + } + + if (m->body) + append_iovec(m, m->body, m->header->body_size); +} + bool bus_socket_auth_needs_write(sd_bus *b) { unsigned i; @@ -729,9 +762,11 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { assert(idx); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); - if (*idx >= m->size) + if (*idx >= bus_message_size(m)) return 0; + bus_message_setup_iovec(m); + n = m->n_iovec * sizeof(struct iovec); iov = alloca(n); memcpy(iov, m->iovec, n); |