aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2021-08-22 16:03:21 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2021-08-22 16:15:38 +0200
commitde21e6ef3d9af96d2b71e54d8148d28b5fc9f22e (patch)
treedc153c0cf6ac08e6f0f5508dcc2603618f314ef6
parentdb1b0ee3b30fd4cd323907c7f24bd575c22e68f0 (diff)
downloadrneovim-de21e6ef3d9af96d2b71e54d8148d28b5fc9f22e.tar.gz
rneovim-de21e6ef3d9af96d2b71e54d8148d28b5fc9f22e.tar.bz2
rneovim-de21e6ef3d9af96d2b71e54d8148d28b5fc9f22e.zip
refactor(map): remove extra-allocating map_new/map_free functions
Note: the reason for removing them is not that there after this refactor is no use of them, but rather that having them available is an anti-pattern: they manange an _extra_ heap allocation which has nothing to do with the functionality of the map itself (khash manages the real buffers internally). In case there happens to be a reason to allocate the map structure itself later, this should be made explicit using xcalloc/xfree calls.
-rw-r--r--src/nvim/api/private/dispatch.c6
-rw-r--r--src/nvim/api/private/helpers.c2
-rw-r--r--src/nvim/api/vim.c4
-rw-r--r--src/nvim/channel.c15
-rw-r--r--src/nvim/channel.h4
-rw-r--r--src/nvim/eval.c19
-rw-r--r--src/nvim/extmark.c2
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua2
-rw-r--r--src/nvim/lua/executor.c17
-rw-r--r--src/nvim/lua/treesitter.c16
-rw-r--r--src/nvim/map.c13
-rw-r--r--src/nvim/map.h8
-rw-r--r--src/nvim/msgpack_rpc/channel.c18
-rw-r--r--src/nvim/msgpack_rpc/channel_defs.h2
-rw-r--r--src/nvim/os/env.c15
-rw-r--r--src/nvim/terminal.c25
16 files changed, 69 insertions, 99 deletions
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index eae4581f42..9f16da4078 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -21,12 +21,12 @@
#include "nvim/api/window.h"
#include "nvim/api/deprecated.h"
-static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
+static Map(String, MsgpackRpcRequestHandler) methods = MAP_INIT;
static void msgpack_rpc_add_method_handler(String method,
MsgpackRpcRequestHandler handler)
{
- map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
+ map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler);
}
/// @param name API method name
@@ -37,7 +37,7 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
{
String m = { .data = (char *)name, .size = name_len };
MsgpackRpcRequestHandler rv =
- map_get(String, MsgpackRpcRequestHandler)(methods, m);
+ map_get(String, MsgpackRpcRequestHandler)(&methods, m);
if (!rv.fn) {
api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 6114500277..eedcfd69b8 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1724,7 +1724,7 @@ const char *describe_ns(NS ns_id)
{
String name;
handle_T id;
- map_foreach((&namespace_ids), name, id, {
+ map_foreach(&namespace_ids, name, id, {
if ((NS)id == ns_id && name.size) {
return name.data;
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 5aed85ef08..90c43a1b04 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -63,7 +63,7 @@ void api_vim_free_all_mem(void)
{
String name;
handle_T id;
- map_foreach((&namespace_ids), name, id, {
+ map_foreach(&namespace_ids, name, id, {
(void)id;
xfree(name.data);
})
@@ -1584,7 +1584,7 @@ Dictionary nvim_get_namespaces(void)
String name;
handle_T id;
- map_foreach((&namespace_ids), name, id, {
+ map_foreach(&namespace_ids, name, id, {
PUT(retval, name.data, INTEGER_OBJ(id));
})
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 0cab916c45..6f12d2eab8 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -32,13 +32,9 @@ static uint64_t next_chan_id = CHAN_STDERR+1;
/// Teardown the module
void channel_teardown(void)
{
- if (!channels) {
- return;
- }
-
Channel *channel;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
channel_close(channel->id, kChannelPartAll, NULL);
});
}
@@ -152,7 +148,6 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
/// Initializes the module
void channel_init(void)
{
- channels = pmap_new(uint64_t)();
channel_alloc(kChannelStreamStderr);
rpc_init();
}
@@ -177,7 +172,7 @@ Channel *channel_alloc(ChannelStreamType type)
chan->exit_status = -1;
chan->streamtype = type;
assert(chan->id <= VARNUMBER_MAX);
- pmap_put(uint64_t)(channels, chan->id, chan);
+ pmap_put(uint64_t)(&channels, chan->id, chan);
return chan;
}
@@ -249,7 +244,7 @@ static void free_channel_event(void **argv)
callback_reader_free(&chan->on_stderr);
callback_free(&chan->on_exit);
- pmap_del(uint64_t)(channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id);
multiqueue_free(chan->events);
xfree(chan);
}
@@ -259,7 +254,7 @@ static void channel_destroy_early(Channel *chan)
if ((chan->id != --next_chan_id)) {
abort();
}
- pmap_del(uint64_t)(channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id);
chan->id = 0;
if ((--chan->refcount != 0)) {
@@ -899,7 +894,7 @@ Array channel_all_info(void)
{
Channel *channel;
Array ret = ARRAY_DICT_INIT;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
ADD(ret, DICTIONARY_OBJ(channel_info(channel->id)));
});
return ret;
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
index df858e1602..9bc0df3615 100644
--- a/src/nvim/channel.h
+++ b/src/nvim/channel.h
@@ -89,7 +89,7 @@ struct Channel {
bool callback_scheduled;
};
-EXTERN PMap(uint64_t) *channels INIT(= NULL);
+EXTERN PMap(uint64_t) channels INIT(= MAP_INIT);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "channel.h.generated.h"
@@ -98,7 +98,7 @@ EXTERN PMap(uint64_t) *channels INIT(= NULL);
/// @returns Channel with the id or NULL if not found
static inline Channel *find_channel(uint64_t id)
{
- return pmap_get(uint64_t)(channels, id);
+ return pmap_get(uint64_t)(&channels, id);
}
static inline Stream *channel_instream(Channel *chan)
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 36b04c24bf..5e18a77b6d 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -265,7 +265,7 @@ static partial_T *vvlua_partial;
#endif
static uint64_t last_timer_id = 1;
-static PMap(uint64_t) *timers = NULL;
+static PMap(uint64_t) timers = MAP_INIT;
static const char *const msgpack_type_names[] = {
[kMPNil] = "nil",
@@ -326,7 +326,6 @@ void eval_init(void)
{
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- timers = pmap_new(uint64_t)();
struct vimvar *p;
init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
@@ -4883,7 +4882,7 @@ bool garbage_collect(bool testing)
// Channels
{
Channel *data;
- map_foreach_value(channels, data, {
+ map_foreach_value(&channels, data, {
set_ref_in_callback_reader(&data->on_data, copyID, NULL, NULL);
set_ref_in_callback_reader(&data->on_stderr, copyID, NULL, NULL);
set_ref_in_callback(&data->on_exit, copyID, NULL, NULL);
@@ -4893,7 +4892,7 @@ bool garbage_collect(bool testing)
// Timers
{
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
set_ref_in_callback(&timer->callback, copyID, NULL, NULL);
})
}
@@ -7304,7 +7303,7 @@ static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
timer_T *find_timer_by_nr(varnumber_T xx)
{
- return pmap_get(uint64_t)(timers, xx);
+ return pmap_get(uint64_t)(&timers, xx);
}
void add_timer_info(typval_T *rettv, timer_T *timer)
@@ -7331,9 +7330,9 @@ void add_timer_info(typval_T *rettv, timer_T *timer)
void add_timer_info_all(typval_T *rettv)
{
- tv_list_alloc_ret(rettv, map_size(timers));
+ tv_list_alloc_ret(rettv, map_size(&timers));
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
if (!timer->stopped) {
add_timer_info(rettv, timer);
}
@@ -7413,7 +7412,7 @@ uint64_t timer_start(const long timeout,
timer->tw.blockable = true;
time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout);
- pmap_put(uint64_t)(timers, timer->timer_id, timer);
+ pmap_put(uint64_t)(&timers, timer->timer_id, timer);
return timer->timer_id;
}
@@ -7435,7 +7434,7 @@ static void timer_close_cb(TimeWatcher *tw, void *data)
timer_T *timer = (timer_T *)data;
multiqueue_free(timer->tw.events);
callback_free(&timer->callback);
- pmap_del(uint64_t)(timers, timer->timer_id);
+ pmap_del(uint64_t)(&timers, timer->timer_id);
timer_decref(timer);
}
@@ -7449,7 +7448,7 @@ static void timer_decref(timer_T *timer)
void timer_stop_all(void)
{
timer_T *timer;
- map_foreach_value(timers, timer, {
+ map_foreach_value(&timers, timer, {
timer_stop(timer);
})
}
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 510f3a4254..b4f22dbf33 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -260,7 +260,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
}
uint64_t id;
ssize_t decor_id;
- map_foreach((&delete_set), id, decor_id, {
+ map_foreach(&delete_set, id, decor_id, {
mtpos_t pos = marktree_lookup(buf->b_marktree, id, itr);
assert(itr->node);
marktree_del_itr(buf->b_marktree, itr, false);
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index 1d41cabfa4..c14b465f92 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -321,8 +321,6 @@ end
output:write([[
void msgpack_rpc_init_method_table(void)
{
- methods = map_new(String, MsgpackRpcRequestHandler)();
-
]])
for i = 1, #functions do
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 8779d16116..cbc2273bc9 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -68,7 +68,8 @@ typedef struct {
}
#if __has_feature(address_sanitizer)
- PMap(handle_T) *nlua_ref_markers = NULL;
+ static PMap(handle_T) nlua_ref_markers = MAP_INIT;
+ static bool nlua_track_refs = false;
# define NLUA_TRACK_REFS
#endif
@@ -568,7 +569,7 @@ void nlua_init(void)
#ifdef NLUA_TRACK_REFS
const char *env = os_getenv("NVIM_LUA_NOTRACK");
if (!env || !*env) {
- nlua_ref_markers = pmap_new(handle_T)();
+ nlua_track_refs = true;
}
#endif
@@ -599,10 +600,10 @@ void nlua_free_all_mem(void)
fprintf(stderr, "%d lua references were leaked!", nlua_refcount);
}
- if (nlua_ref_markers) {
+ if (nlua_track_refs) {
// in case there are leaked luarefs, leak the associated memory
// to get LeakSanitizer stacktraces on exit
- pmap_free(handle_T)(nlua_ref_markers);
+ pmap_destroy(handle_T)(&nlua_ref_markers);
}
#endif
@@ -1001,9 +1002,9 @@ LuaRef nlua_ref(lua_State *lstate, int index)
if (ref > 0) {
nlua_refcount++;
#ifdef NLUA_TRACK_REFS
- if (nlua_ref_markers) {
+ if (nlua_track_refs) {
// dummy allocation to make LeakSanitizer track our luarefs
- pmap_put(handle_T)(nlua_ref_markers, ref, xmalloc(3));
+ pmap_put(handle_T)(&nlua_ref_markers, ref, xmalloc(3));
}
#endif
}
@@ -1017,8 +1018,8 @@ void nlua_unref(lua_State *lstate, LuaRef ref)
nlua_refcount--;
#ifdef NLUA_TRACK_REFS
// NB: don't remove entry from map to track double-unref
- if (nlua_ref_markers) {
- xfree(pmap_get(handle_T)(nlua_ref_markers, ref));
+ if (nlua_track_refs) {
+ xfree(pmap_get(handle_T)(&nlua_ref_markers, ref));
}
#endif
luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index 14fed0d474..2d83620dcd 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -101,7 +101,7 @@ static struct luaL_Reg treecursor_meta[] = {
{ NULL, NULL }
};
-static PMap(cstr_t) *langs;
+static PMap(cstr_t) langs = MAP_INIT;
static void build_meta(lua_State *L, const char *tname, const luaL_Reg *meta)
{
@@ -119,8 +119,6 @@ static void build_meta(lua_State *L, const char *tname, const luaL_Reg *meta)
/// all global state is stored in the regirstry of the lua_State
void tslua_init(lua_State *L)
{
- langs = pmap_new(cstr_t)();
-
// type metatables
build_meta(L, TS_META_PARSER, parser_meta);
build_meta(L, TS_META_TREE, tree_meta);
@@ -133,7 +131,7 @@ void tslua_init(lua_State *L)
int tslua_has_language(lua_State *L)
{
const char *lang_name = luaL_checkstring(L, 1);
- lua_pushboolean(L, pmap_has(cstr_t)(langs, lang_name));
+ lua_pushboolean(L, pmap_has(cstr_t)(&langs, lang_name));
return 1;
}
@@ -142,7 +140,7 @@ int tslua_add_language(lua_State *L)
const char *path = luaL_checkstring(L, 1);
const char *lang_name = luaL_checkstring(L, 2);
- if (pmap_has(cstr_t)(langs, lang_name)) {
+ if (pmap_has(cstr_t)(&langs, lang_name)) {
return 0;
}
@@ -185,7 +183,7 @@ int tslua_add_language(lua_State *L)
TREE_SITTER_LANGUAGE_VERSION, lang_version);
}
- pmap_put(cstr_t)(langs, xstrdup(lang_name), lang);
+ pmap_put(cstr_t)(&langs, xstrdup(lang_name), lang);
lua_pushboolean(L, true);
return 1;
@@ -195,7 +193,7 @@ int tslua_inspect_lang(lua_State *L)
{
const char *lang_name = luaL_checkstring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
@@ -243,7 +241,7 @@ int tslua_push_parser(lua_State *L)
// Gather language name
const char *lang_name = luaL_checkstring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
@@ -1127,7 +1125,7 @@ int tslua_parse_query(lua_State *L)
}
const char *lang_name = lua_tostring(L, 1);
- TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name);
+ TSLanguage *lang = pmap_get(cstr_t)(&langs, lang_name);
if (!lang) {
return luaL_error(L, "no such language: %s", lang_name);
}
diff --git a/src/nvim/map.c b/src/nvim/map.c
index d956699b21..ccd332192e 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -54,19 +54,6 @@
INITIALIZER_DECLARE(T, U, __VA_ARGS__); \
__KHASH_IMPL(T##_##U##_map,, T, U, 1, T##_hash, T##_eq) \
\
- Map(T, U) *map_##T##_##U##_new() \
- { \
- Map(T, U) *rv = xcalloc(1, sizeof(Map(T, U))); \
- /* khash_t table member is zero-initialized */ \
- return rv; \
- } \
- \
- void map_##T##_##U##_free(Map(T, U) *map) \
- { \
- kh_dealloc(T##_##U##_map, &map->table); \
- xfree(map); \
- } \
- \
void map_##T##_##U##_destroy(Map(T, U) *map) \
{ \
kh_dealloc(T##_##U##_map, &map->table); \
diff --git a/src/nvim/map.h b/src/nvim/map.h
index 6dc36f77ac..d6515878a2 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -62,8 +62,6 @@ MAP_DECLS(ColorKey, ColorItem)
#define MAP_INIT { { 0, 0, 0, 0, NULL, NULL, NULL } }
#define map_init(k, v, map) do { *(map) = (Map(k, v))MAP_INIT; } while (false)
-#define map_new(T, U) map_##T##_##U##_new
-#define map_free(T, U) map_##T##_##U##_free
#define map_destroy(T, U) map_##T##_##U##_destroy
#define map_get(T, U) map_##T##_##U##_get
#define map_has(T, U) map_##T##_##U##_has
@@ -75,8 +73,6 @@ MAP_DECLS(ColorKey, ColorItem)
#define map_size(map) ((map)->table.size)
-#define pmap_new(T) map_new(T, ptr_t)
-#define pmap_free(T) map_free(T, ptr_t)
#define pmap_destroy(T) map_destroy(T, ptr_t)
#define pmap_get(T) map_get(T, ptr_t)
#define pmap_has(T) map_has(T, ptr_t)
@@ -89,10 +85,10 @@ MAP_DECLS(ColorKey, ColorItem)
#define pmap_init(k, map) map_init(k, ptr_t, map)
#define map_foreach(map, key, value, block) \
- kh_foreach(&map->table, key, value, block)
+ kh_foreach(&(map)->table, key, value, block)
#define map_foreach_value(map, value, block) \
- kh_foreach_value(&map->table, value, block)
+ kh_foreach_value(&(map)->table, value, block)
void pmap_del2(PMap(cstr_t) *map, const char *key);
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index a2d8859c68..e5743f345b 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -38,7 +38,7 @@
#define log_server_msg(...)
#endif
-static PMap(cstr_t) *event_strings = NULL;
+static PMap(cstr_t) event_strings = MAP_INIT;
static msgpack_sbuffer out_buffer;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -48,7 +48,6 @@ static msgpack_sbuffer out_buffer;
void rpc_init(void)
{
ch_before_blocking_events = multiqueue_new_child(main_loop.events);
- event_strings = pmap_new(cstr_t)();
msgpack_sbuffer_init(&out_buffer);
}
@@ -60,7 +59,6 @@ void rpc_start(Channel *channel)
RpcState *rpc = &channel->rpc;
rpc->closed = false;
rpc->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
- rpc->subscribed_events = pmap_new(cstr_t)();
rpc->next_request_id = 1;
rpc->info = (Dictionary)ARRAY_DICT_INIT;
kv_init(rpc->call_stack);
@@ -183,11 +181,11 @@ void rpc_subscribe(uint64_t id, char *event)
abort();
}
- char *event_string = pmap_get(cstr_t)(event_strings, event);
+ char *event_string = pmap_get(cstr_t)(&event_strings, event);
if (!event_string) {
event_string = xstrdup(event);
- pmap_put(cstr_t)(event_strings, event_string, event_string);
+ pmap_put(cstr_t)(&event_strings, event_string, event_string);
}
pmap_put(cstr_t)(channel->rpc.subscribed_events, event_string, event_string);
@@ -497,7 +495,7 @@ static void broadcast_event(const char *name, Array args)
kvec_t(Channel *) subscribed = KV_INITIAL_VALUE;
Channel *channel;
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
if (channel->is_rpc
&& pmap_has(cstr_t)(channel->rpc.subscribed_events, name)) {
kv_push(subscribed, channel);
@@ -528,7 +526,7 @@ end:
static void unsubscribe(Channel *channel, char *event)
{
- char *event_string = pmap_get(cstr_t)(event_strings, event);
+ char *event_string = pmap_get(cstr_t)(&event_strings, event);
if (!event_string) {
WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'",
channel->id, event);
@@ -536,7 +534,7 @@ static void unsubscribe(Channel *channel, char *event)
}
pmap_del(cstr_t)(channel->rpc.subscribed_events, event_string);
- map_foreach_value(channels, channel, {
+ map_foreach_value(&channels, channel, {
if (channel->is_rpc
&& pmap_has(cstr_t)(channel->rpc.subscribed_events, event_string)) {
return;
@@ -544,7 +542,7 @@ static void unsubscribe(Channel *channel, char *event)
});
// Since the string is no longer used by other channels, release it's memory
- pmap_del(cstr_t)(event_strings, event_string);
+ pmap_del(cstr_t)(&event_strings, event_string);
xfree(event_string);
}
@@ -583,7 +581,7 @@ void rpc_free(Channel *channel)
unsubscribe(channel, event_string);
});
- pmap_free(cstr_t)(channel->rpc.subscribed_events);
+ pmap_destroy(cstr_t)(channel->rpc.subscribed_events);
kv_destroy(channel->rpc.call_stack);
api_free_dictionary(channel->rpc.info);
}
diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h
index 6ef8c027f0..de328af1ce 100644
--- a/src/nvim/msgpack_rpc/channel_defs.h
+++ b/src/nvim/msgpack_rpc/channel_defs.h
@@ -27,7 +27,7 @@ typedef struct {
} RequestEvent;
typedef struct {
- PMap(cstr_t) *subscribed_events;
+ PMap(cstr_t) subscribed_events[1];
bool closed;
msgpack_unpacker *unpacker;
uint32_t next_request_id;
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 008f5ef63b..92b5e14824 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -35,12 +35,11 @@
// Because `uv_os_getenv` requires allocating, we must manage a map to maintain
// the behavior of `os_getenv`.
-static PMap(cstr_t) *envmap;
+static PMap(cstr_t) envmap = MAP_INIT;
static uv_mutex_t mutex;
void env_init(void)
{
- envmap = pmap_new(cstr_t)();
uv_mutex_init(&mutex);
}
@@ -66,8 +65,8 @@ const char *os_getenv(const char *name)
}
uv_mutex_lock(&mutex);
int r = 0;
- if (pmap_has(cstr_t)(envmap, name)
- && !!(e = (char *)pmap_get(cstr_t)(envmap, name))) {
+ if (pmap_has(cstr_t)(&envmap, name)
+ && !!(e = (char *)pmap_get(cstr_t)(&envmap, name))) {
if (e[0] != '\0') {
// Found non-empty cached env var.
// NOTE: This risks incoherence if an in-process library changes the
@@ -75,7 +74,7 @@ const char *os_getenv(const char *name)
// that turns out to be a problem, we can just remove this codepath.
goto end;
}
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
}
e = xmalloc(size);
r = uv_os_getenv(name, e, &size);
@@ -88,7 +87,7 @@ const char *os_getenv(const char *name)
e = NULL;
goto end;
}
- pmap_put(cstr_t)(envmap, xstrdup(name), e);
+ pmap_put(cstr_t)(&envmap, xstrdup(name), e);
end:
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
@@ -157,7 +156,7 @@ int os_setenv(const char *name, const char *value, int overwrite)
assert(r != UV_EINVAL);
// Destroy the old map item. Do this AFTER uv_os_setenv(), because `value`
// could be a previous os_getenv() result.
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
if (r != 0) {
@@ -174,7 +173,7 @@ int os_unsetenv(const char *name)
return -1;
}
uv_mutex_lock(&mutex);
- pmap_del2(envmap, name);
+ pmap_del2(&envmap, name);
int r = uv_os_unsetenv(name);
// Must do this before ELOG, log.c may call os_setenv.
uv_mutex_unlock(&mutex);
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 88dd9db6d1..3335fa500a 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -152,11 +152,10 @@ static VTermScreenCallbacks vterm_screen_callbacks = {
.sb_popline = term_sb_pop,
};
-static PMap(ptr_t) *invalidated_terminals;
+static PMap(ptr_t) invalidated_terminals = MAP_INIT;
void terminal_init(void)
{
- invalidated_terminals = pmap_new(ptr_t)();
time_watcher_init(&main_loop, &refresh_timer, NULL);
// refresh_timer_cb will redraw the screen which can call vimscript
refresh_timer.events = multiqueue_new_child(main_loop.events);
@@ -167,8 +166,10 @@ void terminal_teardown(void)
time_watcher_stop(&refresh_timer);
multiqueue_free(refresh_timer.events);
time_watcher_close(&refresh_timer, NULL);
- pmap_free(ptr_t)(invalidated_terminals);
- invalidated_terminals = NULL;
+ pmap_destroy(ptr_t)(&invalidated_terminals);
+ // terminal_destroy might be called after terminal_teardown is invoked
+ // make sure it is in an empty, valid state
+ pmap_init(ptr_t, &invalidated_terminals);
}
// public API {{{
@@ -525,14 +526,12 @@ void terminal_destroy(Terminal *term)
}
if (!term->refcount) {
- // might be destroyed after terminal_teardown is invoked
- if (invalidated_terminals
- && pmap_has(ptr_t)(invalidated_terminals, term)) {
+ if (pmap_has(ptr_t)(&invalidated_terminals, term)) {
// flush any pending changes to the buffer
block_autocmds();
refresh_terminal(term);
unblock_autocmds();
- pmap_del(ptr_t)(invalidated_terminals, term);
+ pmap_del(ptr_t)(&invalidated_terminals, term);
}
for (size_t i = 0; i < term->sb_current; i++) {
xfree(term->sb_buffer[i]);
@@ -869,7 +868,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
}
memcpy(sbrow->cells, cells, sizeof(cells[0]) * c);
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
return 1;
}
@@ -910,7 +909,7 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
}
xfree(sbrow);
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
return 1;
}
@@ -1212,7 +1211,7 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row)
term->invalid_end = MAX(term->invalid_end, end_row);
}
- pmap_put(ptr_t)(invalidated_terminals, term, NULL);
+ pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
if (!refresh_pending) {
time_watcher_start(&refresh_timer, refresh_timer_cb, REFRESH_DELAY, 0);
refresh_pending = true;
@@ -1254,10 +1253,10 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
void *stub; (void)(stub);
// don't process autocommands while updating terminal buffers
block_autocmds();
- map_foreach(invalidated_terminals, term, stub, {
+ map_foreach(&invalidated_terminals, term, stub, {
refresh_terminal(term);
});
- pmap_clear(ptr_t)(invalidated_terminals);
+ pmap_clear(ptr_t)(&invalidated_terminals);
unblock_autocmds();
}