diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2021-08-22 16:03:21 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2021-08-22 16:15:38 +0200 |
commit | de21e6ef3d9af96d2b71e54d8148d28b5fc9f22e (patch) | |
tree | dc153c0cf6ac08e6f0f5508dcc2603618f314ef6 | |
parent | db1b0ee3b30fd4cd323907c7f24bd575c22e68f0 (diff) | |
download | rneovim-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.c | 6 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 2 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 4 | ||||
-rw-r--r-- | src/nvim/channel.c | 15 | ||||
-rw-r--r-- | src/nvim/channel.h | 4 | ||||
-rw-r--r-- | src/nvim/eval.c | 19 | ||||
-rw-r--r-- | src/nvim/extmark.c | 2 | ||||
-rw-r--r-- | src/nvim/generators/gen_api_dispatch.lua | 2 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 17 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 16 | ||||
-rw-r--r-- | src/nvim/map.c | 13 | ||||
-rw-r--r-- | src/nvim/map.h | 8 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.c | 18 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/os/env.c | 15 | ||||
-rw-r--r-- | src/nvim/terminal.c | 25 |
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(); } |