mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00
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.
This commit is contained in:
@@ -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",
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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));
|
||||
})
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
})
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -321,8 +321,6 @@ end
|
||||
output:write([[
|
||||
void msgpack_rpc_init_method_table(void)
|
||||
{
|
||||
methods = map_new(String, MsgpackRpcRequestHandler)();
|
||||
|
||||
]])
|
||||
|
||||
for i = 1, #functions do
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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); \
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user