Commit 2100fa10 authored by Lennart Poettering's avatar Lennart Poettering

bus: calculate iovec for messages only when we need it

parent 9be9c7cf
......@@ -302,7 +302,6 @@ int bus_message_from_malloc(
m->n_iovec = 1;
m->iovec[0].iov_base = buffer;
m->iovec[0].iov_len = length;
m->size = length;
r = message_parse_fields(m);
if (r < 0)
......@@ -2794,42 +2793,6 @@ static int message_parse_fields(sd_bus_message *m) {
return 0;
}
static void setup_iovec(sd_bus_message *m) {
assert(m);
assert(m->sealed);
m->n_iovec = 0;
m->size = 0;
m->iovec[m->n_iovec].iov_base = m->header;
m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
if (m->fields) {
m->iovec[m->n_iovec].iov_base = m->fields;
m->iovec[m->n_iovec].iov_len = m->header->fields_size;
m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
if (m->header->fields_size % 8 != 0) {
static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
m->iovec[m->n_iovec].iov_base = (void*) padding;
m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
}
}
if (m->body) {
m->iovec[m->n_iovec].iov_base = m->body;
m->iovec[m->n_iovec].iov_len = m->header->body_size;
m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
}
}
int bus_message_seal(sd_bus_message *m, uint64_t serial) {
int r;
......@@ -2857,8 +2820,6 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) {
m->header->serial = serial;
m->sealed = true;
setup_iovec(m);
return 0;
}
......@@ -3074,22 +3035,31 @@ int bus_message_dump(sd_bus_message *m) {
int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
size_t total;
unsigned i;
void *p, *e;
assert(m);
assert(buffer);
assert(sz);
for (i = 0, total = 0; i < m->n_iovec; i++)
total += m->iovec[i].iov_len;
total = bus_message_size(m);
p = malloc(total);
if (!p)
return -ENOMEM;
for (i = 0, e = p; i < m->n_iovec; i++)
e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
e = mempcpy(p, m->header, sizeof(*m->header));
if (m->fields) {
e = mempcpy(e, m->fields, m->header->fields_size);
if (m->header->fields_size % 8 != 0)
e = mempset(e, 0, 8 - (m->header->fields_size % 8));
}
if (m->body)
e = mempcpy(e, m->body, m->header->body_size);
assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
*buffer = p;
*sz = total;
......@@ -3162,3 +3132,13 @@ const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
return t;
}
size_t bus_message_size(sd_bus_message *m) {
assert(m);
assert(m->sealed);
return
sizeof(*m->header) +
ALIGN8(m->header->fields_size) +
m->header->body_size;
}
......@@ -92,7 +92,6 @@ struct sd_bus_message {
struct iovec iovec[4];
unsigned n_iovec;
size_t size;
char *peeked_signature;
};
......@@ -146,3 +145,5 @@ int bus_message_from_malloc(
const char* bus_message_get_arg(sd_bus_message *m, unsigned i);
int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
size_t bus_message_size(sd_bus_message *m);
......@@ -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);
......
......@@ -965,7 +965,7 @@ static int dispatch_wqueue(sd_bus *bus) {
} else if (r == 0)
/* Didn't do anything this time */
return ret;
else if (bus->windex >= bus->wqueue[0]->size) {
else if (bus->windex >= bus_message_size(bus->wqueue[0])) {
/* Fully written. Let's drop the entry from
* the queue.
*
......@@ -1066,7 +1066,7 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
if (r < 0) {
sd_bus_close(bus);
return r;
} else if (idx < m->size) {
} else if (idx < bus_message_size(m)) {
/* Wasn't fully written. So let's remember how
* much was written. Note that the first entry
* of the wqueue array is always allocated so
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment