From 4d39861f991254aa381b8823476825e26a4d6da3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Jan 2004 04:32:17 +0000 Subject: avoid a copy of the data being input to the dcerpc server in the most common case of there being no pending partial data and a full dcerpc packet being received. We should use this same model for the smb server. It gives us efficient memory usage while allowing for completely async socket operations. (This used to be commit 9aab321fb6e2f3499efd8ca5bc88ce2cb8e68219) --- source4/rpc_server/dcerpc_server.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 46341e6db1..a4f5fb9768 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -689,15 +689,14 @@ static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32 offse DATA_BLOB blob; if (dce_conn->partial_input.length == offset) { - free(dce_conn->partial_input.data); - dce_conn->partial_input = data_blob(NULL, 0); + data_blob_free(&dce_conn->partial_input); return; } blob = dce_conn->partial_input; dce_conn->partial_input = data_blob(blob.data + offset, - blob.length - offset); - free(blob.data); + blob.length - offset); + data_blob_free(&blob); } /* @@ -840,6 +839,32 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; + /* handle the very common case that the input contains a full packet and there + is no partial packet pending. In this case we can avoid a copy of the + data */ + if (dce_conn->partial_input.length == 0) { + dce_conn->partial_input = *data; + /* make sure that dce_partial_advance doesn't free this data */ + dce_conn->partial_input.free = NULL; + while (dce_full_packet(&dce_conn->partial_input)) { + status = dcesrv_input_process(dce_conn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + if (dce_conn->partial_input.length) { + /* there was some data left over. We have to copy this + as the caller may free the data */ + dce_conn->partial_input = + data_blob(dce_conn->partial_input.data, + dce_conn->partial_input.length); + if (!dce_conn->partial_input.data) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; + } + dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { -- cgit