mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Merge pull request #30558 from bfredl/noklist
refactor(event): change last use of klist to kvec
This commit is contained in:
commit
69553f7bf5
144
src/klib/klist.h
144
src/klib/klist.h
@ -1,144 +0,0 @@
|
||||
/* The MIT License
|
||||
|
||||
Copyright (c) 2008-2009, by Attractive Chaos <attractor@live.co.uk>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _AC_KLIST_H
|
||||
#define _AC_KLIST_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nvim/func_attr.h"
|
||||
#include "nvim/memory.h"
|
||||
|
||||
#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \
|
||||
typedef struct { \
|
||||
size_t cnt, n, max; \
|
||||
kmptype_t **buf; \
|
||||
} kmp_##name##_t; \
|
||||
static inline kmp_##name##_t *kmp_init_##name(void) { \
|
||||
return (kmp_##name##_t *)xcalloc(1, sizeof(kmp_##name##_t)); \
|
||||
} \
|
||||
static inline void kmp_destroy_##name(kmp_##name##_t *mp) \
|
||||
REAL_FATTR_UNUSED; \
|
||||
static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \
|
||||
size_t k; \
|
||||
for (k = 0; k < mp->n; k++) { \
|
||||
kmpfree_f(mp->buf[k]); XFREE_CLEAR(mp->buf[k]); \
|
||||
} \
|
||||
XFREE_CLEAR(mp->buf); XFREE_CLEAR(mp); \
|
||||
} \
|
||||
static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \
|
||||
mp->cnt++; \
|
||||
if (mp->n == 0) { \
|
||||
return (kmptype_t *)xcalloc(1, sizeof(kmptype_t)); \
|
||||
} \
|
||||
return mp->buf[--mp->n]; \
|
||||
} \
|
||||
static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \
|
||||
mp->cnt--; \
|
||||
if (mp->n == mp->max) { \
|
||||
mp->max = mp->max ? (mp->max << 1) : 16; \
|
||||
mp->buf = (kmptype_t **)xrealloc(mp->buf, sizeof(kmptype_t *) * mp->max); \
|
||||
} \
|
||||
mp->buf[mp->n++] = p; \
|
||||
}
|
||||
|
||||
#define kmempool_t(name) kmp_##name##_t
|
||||
#define kmp_init(name) kmp_init_##name()
|
||||
#define kmp_destroy(name, mp) kmp_destroy_##name(mp)
|
||||
#define kmp_alloc(name, mp) kmp_alloc_##name(mp)
|
||||
#define kmp_free(name, mp, p) kmp_free_##name(mp, p)
|
||||
|
||||
#define KLIST_INIT(name, kltype_t, kmpfree_t) \
|
||||
struct __kl1_##name { \
|
||||
kltype_t data; \
|
||||
struct __kl1_##name *next; \
|
||||
}; \
|
||||
typedef struct __kl1_##name kl1_##name; \
|
||||
KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \
|
||||
typedef struct { \
|
||||
kl1_##name *head, *tail; \
|
||||
kmp_##name##_t *mp; \
|
||||
size_t size; \
|
||||
} kl_##name##_t; \
|
||||
static inline kl_##name##_t *kl_init_##name(void) { \
|
||||
kl_##name##_t *kl = (kl_##name##_t *)xcalloc(1, sizeof(kl_##name##_t)); \
|
||||
kl->mp = kmp_init(name); \
|
||||
kl->head = kl->tail = kmp_alloc(name, kl->mp); \
|
||||
kl->head->next = 0; \
|
||||
return kl; \
|
||||
} \
|
||||
static inline void kl_destroy_##name(kl_##name##_t *kl) \
|
||||
REAL_FATTR_UNUSED; \
|
||||
static inline void kl_destroy_##name(kl_##name##_t *kl) { \
|
||||
kl1_##name *p; \
|
||||
for (p = kl->head; p != kl->tail; p = p->next) { \
|
||||
kmp_free(name, kl->mp, p); \
|
||||
} \
|
||||
kmp_free(name, kl->mp, p); \
|
||||
kmp_destroy(name, kl->mp); \
|
||||
XFREE_CLEAR(kl); \
|
||||
} \
|
||||
static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \
|
||||
kl1_##name *q, *p = kmp_alloc(name, kl->mp); \
|
||||
q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \
|
||||
kl->size++; \
|
||||
q->data = d; \
|
||||
} \
|
||||
static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \
|
||||
kl1_##name **n) { \
|
||||
assert((*n)->next); \
|
||||
kl1_##name *p; \
|
||||
kl->size--; \
|
||||
p = *n; \
|
||||
*n = (*n)->next; \
|
||||
if (p == kl->head) { \
|
||||
kl->head = *n; \
|
||||
} \
|
||||
kltype_t d = p->data; \
|
||||
kmp_free(name, kl->mp, p); \
|
||||
return d; \
|
||||
}
|
||||
|
||||
#define kliter_t(name) kl1_##name
|
||||
#define klist_t(name) kl_##name##_t
|
||||
#define kl_val(iter) ((iter)->data)
|
||||
#define kl_next(iter) ((iter)->next)
|
||||
#define kl_begin(kl) ((kl)->head)
|
||||
#define kl_end(kl) ((kl)->tail)
|
||||
|
||||
#define kl_init(name) kl_init_##name()
|
||||
#define kl_destroy(name, kl) kl_destroy_##name(kl)
|
||||
#define kl_push(name, kl, d) kl_push_##name(kl, d)
|
||||
#define kl_shift_at(name, kl, node) kl_shift_at_##name(kl, node)
|
||||
#define kl_shift(name, kl) kl_shift_at(name, kl, &kl->head)
|
||||
#define kl_empty(kl) ((kl)->size == 0)
|
||||
// Iteration macros. It's ok to modify the list while iterating as long as a
|
||||
// `break` statement is executed before the next iteration.
|
||||
#define kl_iter(name, kl, p) kl_iter_at(name, kl, p, NULL)
|
||||
#define kl_iter_at(name, kl, p, h) \
|
||||
for (kl1_##name **p = h ? h : &kl->head; *p != kl->tail; p = &(*p)->next)
|
||||
|
||||
#endif
|
@ -20,7 +20,7 @@ void loop_init(Loop *loop, void *data)
|
||||
loop->recursive = 0;
|
||||
loop->closing = false;
|
||||
loop->uv.data = loop;
|
||||
loop->children = kl_init(WatcherPtr);
|
||||
kv_init(loop->children);
|
||||
loop->events = multiqueue_new_parent(loop_on_put, loop);
|
||||
loop->fast_events = multiqueue_new_child(loop->events);
|
||||
loop->thread_events = multiqueue_new_parent(NULL, NULL);
|
||||
@ -187,7 +187,7 @@ bool loop_close(Loop *loop, bool wait)
|
||||
multiqueue_free(loop->fast_events);
|
||||
multiqueue_free(loop->thread_events);
|
||||
multiqueue_free(loop->events);
|
||||
kl_destroy(WatcherPtr, loop->children);
|
||||
kv_destroy(loop->children);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -3,15 +3,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "klib/klist.h"
|
||||
#include "klib/kvec.h"
|
||||
#include "nvim/event/defs.h" // IWYU pragma: keep
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
typedef void *WatcherPtr;
|
||||
|
||||
#define NOOP(x)
|
||||
KLIST_INIT(WatcherPtr, WatcherPtr, NOOP)
|
||||
|
||||
struct loop {
|
||||
uv_loop_t uv;
|
||||
MultiQueue *events;
|
||||
@ -27,7 +22,7 @@ struct loop {
|
||||
MultiQueue *fast_events;
|
||||
|
||||
// used by process/job-control subsystem
|
||||
klist_t(WatcherPtr) *children;
|
||||
kvec_t(Proc *) children;
|
||||
uv_signal_t children_watcher;
|
||||
uv_timer_t children_kill_timer;
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <signal.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "klib/klist.h"
|
||||
#include "nvim/event/libuv_proc.h"
|
||||
#include "nvim/event/loop.h"
|
||||
#include "nvim/event/multiqueue.h"
|
||||
@ -123,7 +122,7 @@ int proc_spawn(Proc *proc, bool in, bool out, bool err)
|
||||
proc->internal_exit_cb = on_proc_exit;
|
||||
proc->internal_close_cb = decref;
|
||||
proc->refcount++;
|
||||
kl_push(WatcherPtr, proc->loop->children, proc);
|
||||
kv_push(proc->loop->children, proc);
|
||||
DLOG("new: pid=%d exepath=[%s]", proc->pid, proc_get_exepath(proc));
|
||||
return 0;
|
||||
}
|
||||
@ -131,8 +130,8 @@ int proc_spawn(Proc *proc, bool in, bool out, bool err)
|
||||
void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
proc_is_tearing_down = true;
|
||||
kl_iter(WatcherPtr, loop->children, current) {
|
||||
Proc *proc = (*current)->data;
|
||||
for (size_t i = 0; i < kv_size(loop->children); i++) {
|
||||
Proc *proc = kv_A(loop->children, i);
|
||||
if (proc->detach || proc->type == kProcTypePty) {
|
||||
// Close handles to process without killing it.
|
||||
CREATE_EVENT(loop->events, proc_close_handles, proc);
|
||||
@ -143,7 +142,7 @@ void proc_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
|
||||
|
||||
// Wait until all children exit and all close events are processed.
|
||||
LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1,
|
||||
kl_empty(loop->children) && multiqueue_empty(loop->events));
|
||||
kv_size(loop->children) == 0 && multiqueue_empty(loop->events));
|
||||
pty_proc_teardown(loop);
|
||||
}
|
||||
|
||||
@ -254,8 +253,8 @@ static void children_kill_cb(uv_timer_t *handle)
|
||||
{
|
||||
Loop *loop = handle->loop->data;
|
||||
|
||||
kl_iter(WatcherPtr, loop->children, current) {
|
||||
Proc *proc = (*current)->data;
|
||||
for (size_t i = 0; i < kv_size(loop->children); i++) {
|
||||
Proc *proc = kv_A(loop->children, i);
|
||||
bool exited = (proc->status >= 0);
|
||||
if (exited || !proc->stopped_time) {
|
||||
continue;
|
||||
@ -294,15 +293,19 @@ static void decref(Proc *proc)
|
||||
}
|
||||
|
||||
Loop *loop = proc->loop;
|
||||
kliter_t(WatcherPtr) **node = NULL;
|
||||
kl_iter(WatcherPtr, loop->children, current) {
|
||||
if ((*current)->data == proc) {
|
||||
node = current;
|
||||
size_t i;
|
||||
for (i = 0; i < kv_size(loop->children); i++) {
|
||||
Proc *current = kv_A(loop->children, i);
|
||||
if (current == proc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(node);
|
||||
kl_shift_at(WatcherPtr, loop->children, node);
|
||||
assert(i < kv_size(loop->children)); // element found
|
||||
if (i < kv_size(loop->children) - 1) {
|
||||
memmove(&kv_A(loop->children, i), &kv_A(loop->children, i + 1),
|
||||
sizeof(&kv_A(loop->children, i)) * (kv_size(loop->children) - (i + 1)));
|
||||
}
|
||||
kv_size(loop->children)--;
|
||||
CREATE_EVENT(proc->events, proc_close_event, proc);
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#endif
|
||||
|
||||
#include "auto/config.h"
|
||||
#include "klib/klist.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/event/defs.h"
|
||||
#include "nvim/event/loop.h"
|
||||
@ -387,8 +386,8 @@ static void chld_handler(uv_signal_t *handle, int signum)
|
||||
|
||||
Loop *loop = handle->loop->data;
|
||||
|
||||
kl_iter(WatcherPtr, loop->children, current) {
|
||||
Proc *proc = (*current)->data;
|
||||
for (size_t i = 0; i < kv_size(loop->children); i++) {
|
||||
Proc *proc = kv_A(loop->children, i);
|
||||
do {
|
||||
pid = waitpid(proc->pid, &stat, WNOHANG);
|
||||
} while (pid < 0 && errno == EINTR);
|
||||
|
Loading…
Reference in New Issue
Block a user