mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 03:44:06 +00:00
dix: rpcbuf: don't clear memory unless requested explicitly
Instead of always zero'ing out the whole buffer at allocation time, only do it where really necessary. Also adding x_rpcbuf_reserve0() for reserving buffer space that's explicitly cleared. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
committed by
Enrico Weigelt
parent
123652228e
commit
ed47ec4bcb
66
dix/rpcbuf.c
66
dix/rpcbuf.c
@@ -8,32 +8,37 @@
|
||||
|
||||
#include "dix/rpcbuf_priv.h"
|
||||
|
||||
static inline Bool __x_rpcbuf_write_bin_pad(
|
||||
x_rpcbuf_t *rpcbuf, const char *val, size_t len)
|
||||
{
|
||||
const size_t blen = pad_to_int32(len);
|
||||
|
||||
char *reserved = x_rpcbuf_reserve(rpcbuf, blen);
|
||||
if (!reserved)
|
||||
return FALSE;
|
||||
|
||||
memcpy(reserved, val, len);
|
||||
memset(reserved + len, 0, blen - len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool x_rpcbuf_makeroom(x_rpcbuf_t *rpcbuf, size_t needed)
|
||||
{
|
||||
/* break out of alreay in error state */
|
||||
if (rpcbuf->error)
|
||||
return FALSE;
|
||||
|
||||
/* not allocated yet ? */
|
||||
if (!rpcbuf->buffer) {
|
||||
if (!(rpcbuf->buffer = calloc(1, XLIBRE_RPCBUF_CHUNK_SIZE)))
|
||||
goto err;
|
||||
rpcbuf->size = XLIBRE_RPCBUF_CHUNK_SIZE;
|
||||
rpcbuf->wpos = 0;
|
||||
}
|
||||
|
||||
/* still enough space */
|
||||
if (rpcbuf->size > rpcbuf->wpos + needed)
|
||||
return TRUE;
|
||||
|
||||
const size_t newsize = ((needed / XLIBRE_RPCBUF_CHUNK_SIZE) + 1)
|
||||
const size_t newsize = (((rpcbuf->wpos + needed) / XLIBRE_RPCBUF_CHUNK_SIZE) + 1)
|
||||
* XLIBRE_RPCBUF_CHUNK_SIZE;
|
||||
|
||||
char *newbuf = realloc(rpcbuf->buffer, newsize);
|
||||
if (!newbuf)
|
||||
goto err;
|
||||
|
||||
memset(newbuf + rpcbuf->size, 0, newsize - rpcbuf->size);
|
||||
rpcbuf->buffer = newbuf;
|
||||
rpcbuf->size = newsize;
|
||||
|
||||
@@ -61,7 +66,6 @@ void x_rpcbuf_reset(x_rpcbuf_t *rpcbuf)
|
||||
return;
|
||||
|
||||
/* clear memory, but don't free it */
|
||||
memset(rpcbuf->buffer, 0, rpcbuf->size);
|
||||
rpcbuf->wpos = 0;
|
||||
}
|
||||
|
||||
@@ -76,21 +80,22 @@ void *x_rpcbuf_reserve(x_rpcbuf_t *rpcbuf, size_t needed)
|
||||
return pos;
|
||||
}
|
||||
|
||||
void *x_rpcbuf_reserve0(x_rpcbuf_t *rpcbuf, size_t needed)
|
||||
{
|
||||
void *buf = x_rpcbuf_reserve(rpcbuf, needed);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
memset(buf, 0, needed);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Bool x_rpcbuf_write_string_pad(x_rpcbuf_t *rpcbuf, const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return TRUE;
|
||||
|
||||
size_t slen = strlen(str);
|
||||
if (!slen)
|
||||
return TRUE;
|
||||
|
||||
char *reserved = x_rpcbuf_reserve(rpcbuf, pad_to_int32(slen));
|
||||
if (!reserved)
|
||||
return FALSE;
|
||||
|
||||
memcpy(reserved, str, slen);
|
||||
return TRUE;
|
||||
return __x_rpcbuf_write_bin_pad(rpcbuf, str, strlen(str));
|
||||
}
|
||||
|
||||
Bool x_rpcbuf_write_string_0t_pad(x_rpcbuf_t *rpcbuf, const char *str)
|
||||
@@ -98,16 +103,7 @@ Bool x_rpcbuf_write_string_0t_pad(x_rpcbuf_t *rpcbuf, const char *str)
|
||||
if (!str)
|
||||
return x_rpcbuf_write_CARD32(rpcbuf, 0);
|
||||
|
||||
size_t slen = strlen(str);
|
||||
if (!slen)
|
||||
return x_rpcbuf_write_CARD32(rpcbuf, 0);
|
||||
|
||||
char *reserved = x_rpcbuf_reserve(rpcbuf, pad_to_int32(slen+1));
|
||||
if (!reserved)
|
||||
return FALSE;
|
||||
|
||||
memcpy(reserved, str, slen+1);
|
||||
return TRUE;
|
||||
return __x_rpcbuf_write_bin_pad(rpcbuf, str, strlen(str)+1);
|
||||
}
|
||||
|
||||
Bool x_rpcbuf_write_CARD8(x_rpcbuf_t *rpcbuf, CARD8 value)
|
||||
@@ -206,11 +202,5 @@ Bool x_rpcbuf_write_binary_pad(x_rpcbuf_t *rpcbuf, const void *values,
|
||||
if ((!values) || (!size))
|
||||
return TRUE;
|
||||
|
||||
void *reserved = x_rpcbuf_reserve(rpcbuf, pad_to_int32(size));
|
||||
if (!reserved)
|
||||
return FALSE;
|
||||
|
||||
memcpy(reserved, values, size);
|
||||
|
||||
return TRUE;
|
||||
return __x_rpcbuf_write_bin_pad(rpcbuf, values, size);
|
||||
}
|
||||
|
||||
@@ -84,6 +84,23 @@ void x_rpcbuf_reset(x_rpcbuf_t *rpcbuf)
|
||||
void *x_rpcbuf_reserve(x_rpcbuf_t *rpcbuf, size_t needed)
|
||||
_X_ATTRIBUTE_NONNULL_ARG(1);
|
||||
|
||||
/*
|
||||
* like x_rpcbuf_reserve(), but additionally clearing the reserved space.
|
||||
*
|
||||
* the returned poiner can be used to directly write data into the
|
||||
* reserved region. buffer pointer is moved right after that region.
|
||||
*
|
||||
* NOTE: that region is only valid until another operation on this
|
||||
* buffer that might affect the allocated memory block: when buffer
|
||||
* needs to be resized, it may get a new memory location.
|
||||
*
|
||||
* @param rpcbuf pointer to x_rpcbuf_t to operate on
|
||||
* @param needed amount of bytes needed
|
||||
* @return pointer to reserved region of NULL on allocation failure
|
||||
*/
|
||||
void *x_rpcbuf_reserve0(x_rpcbuf_t *rpcbuf, size_t needed)
|
||||
_X_ATTRIBUTE_NONNULL_ARG(1);
|
||||
|
||||
/*
|
||||
* write a plain C string to rpc buffer and pad it.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user