1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#ifndef NVIM_EVENT_LOOP_H
#define NVIM_EVENT_LOOP_H
#include <stdint.h>
#include <uv.h>
#include "klib/klist.h"
#include "nvim/event/multiqueue.h"
#include "nvim/os/time.h"
typedef void *WatcherPtr;
#define _NOOP(x)
KLIST_INIT(WatcherPtr, WatcherPtr, _NOOP)
typedef struct loop {
uv_loop_t uv;
MultiQueue *events;
MultiQueue *thread_events;
// Immediate events:
// "Processed after exiting uv_run() (to avoid recursion), but before
// returning from loop_poll_events()." 502aee690c98
// Practical consequence (for main_loop): these events are processed by
// state_enter()..os_inchar()
// whereas "regular" events (main_loop.events) are processed by
// state_enter()..VimState.execute()
// But state_enter()..os_inchar() can be "too early" if you want the event
// to trigger UI updates and other user-activity-related side-effects.
MultiQueue *fast_events;
// used by process/job-control subsystem
klist_t(WatcherPtr) *children;
uv_signal_t children_watcher;
uv_timer_t children_kill_timer;
// generic timer, used by loop_poll_events()
uv_timer_t poll_timer;
uv_timer_t exit_delay_timer;
uv_async_t async;
uv_mutex_t mutex;
int recursive;
} Loop;
#define CREATE_EVENT(multiqueue, handler, argc, ...) \
do { \
if (multiqueue) { \
multiqueue_put((multiqueue), (handler), argc, __VA_ARGS__); \
} else { \
void *argv[argc] = { __VA_ARGS__ }; \
(handler)(argv); \
} \
} while (0)
// -V:LOOP_PROCESS_EVENTS_UNTIL:547
// Poll for events until a condition or timeout
#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \
do { \
int64_t remaining = timeout; \
uint64_t before = (remaining > 0) ? os_hrtime() : 0; \
while (!(condition)) { \
LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \
if (remaining == 0) { \
break; \
} else if (remaining > 0) { \
uint64_t now = os_hrtime(); \
remaining -= (int64_t)((now - before) / 1000000); \
before = now; \
if (remaining <= 0) { \
break; \
} \
} \
} \
} while (0)
#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \
do { \
if (multiqueue && !multiqueue_empty(multiqueue)) { \
multiqueue_process_events(multiqueue); \
} else { \
loop_poll_events(loop, timeout); \
} \
} while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/loop.h.generated.h"
#endif
#endif // NVIM_EVENT_LOOP_H
|