mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
perf(os/env): os_getenv() allocation when there is no env var set
os_getenv("FOO") caches the result when $FOO is set to something non-empty. However, when $FOO was not set, every new call to os_getenv("FOO") would allocate a temporary scratch buffer to immediately throw away. This has an huge impact e.g. on logging which depends on potentially non-set env vars.
This commit is contained in:
parent
15f7ac6a04
commit
c5990f2cdc
@ -61,8 +61,7 @@ static PMap(cstr_t) envmap = MAP_INIT;
|
|||||||
const char *os_getenv(const char *name)
|
const char *os_getenv(const char *name)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
char *e;
|
char *e = NULL;
|
||||||
size_t size = 64;
|
|
||||||
if (name[0] == '\0') {
|
if (name[0] == '\0') {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -78,23 +77,31 @@ const char *os_getenv(const char *name)
|
|||||||
}
|
}
|
||||||
pmap_del2(&envmap, name);
|
pmap_del2(&envmap, name);
|
||||||
}
|
}
|
||||||
|
#define INIT_SIZE 64
|
||||||
|
size_t size = INIT_SIZE;
|
||||||
|
char buf[INIT_SIZE];
|
||||||
|
r = uv_os_getenv(name, buf, &size);
|
||||||
|
if (r == UV_ENOBUFS) {
|
||||||
e = xmalloc(size);
|
e = xmalloc(size);
|
||||||
r = uv_os_getenv(name, e, &size);
|
r = uv_os_getenv(name, e, &size);
|
||||||
if (r == UV_ENOBUFS) {
|
|
||||||
e = xrealloc(e, size);
|
|
||||||
r = uv_os_getenv(name, e, &size);
|
|
||||||
}
|
|
||||||
if (r != 0 || size == 0 || e[0] == '\0') {
|
if (r != 0 || size == 0 || e[0] == '\0') {
|
||||||
xfree(e);
|
XFREE_CLEAR(e);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else if (r != 0 || size == 0 || buf[0] == '\0') {
|
||||||
e = NULL;
|
e = NULL;
|
||||||
goto end;
|
goto end;
|
||||||
|
} else {
|
||||||
|
// NB: `size` param of uv_os_getenv() includes the NUL-terminator,
|
||||||
|
// except when it does not include the NUL-terminator.
|
||||||
|
e = xmemdupz(buf, size);
|
||||||
}
|
}
|
||||||
pmap_put(cstr_t)(&envmap, xstrdup(name), e);
|
pmap_put(cstr_t)(&envmap, xstrdup(name), e);
|
||||||
end:
|
end:
|
||||||
if (r != 0 && r != UV_ENOENT && r != UV_UNKNOWN) {
|
if (r != 0 && r != UV_ENOENT && r != UV_UNKNOWN) {
|
||||||
ELOG("uv_os_getenv(%s) failed: %d %s", name, r, uv_err_name(r));
|
ELOG("uv_os_getenv(%s) failed: %d %s", name, r, uv_err_name(r));
|
||||||
}
|
}
|
||||||
return (e == NULL || size == 0 || e[0] == '\0') ? NULL : e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if environment variable `name` is defined (even if empty).
|
/// Returns true if environment variable `name` is defined (even if empty).
|
||||||
|
Loading…
Reference in New Issue
Block a user