From e19764f75a2f938e85a1667eccbfc09038ec1b11 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 14 Aug 2015 18:12:56 +0200 Subject: [PATCH] unix: don't copy arguments for sync fs requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For synchronous file operation requests (ones without a callback), there is no need to make a copy of the arguments because they don't outlive the scope of the function call. PR-URL: https://github.com/libuv/libuv/pull/479 Reviewed-By: Saúl Ibarra Corretgé --- src/unix/fs.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index fd7489b4..83c5a423 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -73,24 +73,34 @@ #define PATH \ do { \ - req->path = uv__strdup(path); \ - if (req->path == NULL) \ - return -ENOMEM; \ + assert(path != NULL); \ + if (cb == NULL) { \ + req->path = path; \ + } else { \ + req->path = uv__strdup(path); \ + if (req->path == NULL) \ + return -ENOMEM; \ + } \ } \ while (0) #define PATH2 \ do { \ - size_t path_len; \ - size_t new_path_len; \ - path_len = strlen(path) + 1; \ - new_path_len = strlen(new_path) + 1; \ - req->path = uv__malloc(path_len + new_path_len); \ - if (req->path == NULL) \ - return -ENOMEM; \ - req->new_path = req->path + path_len; \ - memcpy((void*) req->path, path, path_len); \ - memcpy((void*) req->new_path, new_path, new_path_len); \ + if (cb == NULL) { \ + req->path = path; \ + req->new_path = new_path; \ + } else { \ + size_t path_len; \ + size_t new_path_len; \ + path_len = strlen(path) + 1; \ + new_path_len = strlen(new_path) + 1; \ + req->path = uv__malloc(path_len + new_path_len); \ + if (req->path == NULL) \ + return -ENOMEM; \ + req->new_path = req->path + path_len; \ + memcpy((void*) req->path, path, path_len); \ + memcpy((void*) req->new_path, new_path, new_path_len); \ + } \ } \ while (0) @@ -1218,7 +1228,14 @@ int uv_fs_write(uv_loop_t* loop, void uv_fs_req_cleanup(uv_fs_t* req) { - uv__free((void*)req->path); + /* Only necessary for asychronous requests, i.e., requests with a callback. + * Synchronous ones don't copy their arguments and have req->path and + * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the + * exception to the rule, it always allocates memory. + */ + if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP)) + uv__free((void*) req->path); /* Memory is shared with req->new_path. */ + req->path = NULL; req->new_path = NULL;