aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event/defs.h
blob: 20724f9263defea126c66f253d1bc3f8205a1834 (plain) (blame)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#pragma once

#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
#include <uv.h>

#include "nvim/eval/typval_defs.h"
#include "nvim/types_defs.h"

enum { EVENT_HANDLER_MAX_ARGC = 10, };

typedef void (*argv_callback)(void **argv);
typedef struct {
  argv_callback handler;
  void *argv[EVENT_HANDLER_MAX_ARGC];
} Event;

#define event_create(cb, ...) ((Event){ .handler = cb, .argv = { __VA_ARGS__ } })

typedef struct multiqueue MultiQueue;
typedef void (*PutCallback)(MultiQueue *multiq, void *data);

typedef struct signal_watcher SignalWatcher;
typedef void (*signal_cb)(SignalWatcher *watcher, int signum, void *data);
typedef void (*signal_close_cb)(SignalWatcher *watcher, void *data);

struct signal_watcher {
  uv_signal_t uv;
  void *data;
  signal_cb cb;
  signal_close_cb close_cb;
  MultiQueue *events;
};

typedef struct time_watcher TimeWatcher;
typedef void (*time_cb)(TimeWatcher *watcher, void *data);

struct time_watcher {
  uv_timer_t uv;
  void *data;
  time_cb cb, close_cb;
  MultiQueue *events;
  bool blockable;
};

typedef struct wbuffer WBuffer;
typedef void (*wbuffer_data_finalizer)(void *data);

struct wbuffer {
  size_t size, refcount;
  char *data;
  wbuffer_data_finalizer cb;
};

typedef struct stream Stream;
typedef struct rstream RStream;
/// Type of function called when the RStream buffer is filled with data
///
/// @param stream The Stream instance
/// @param read_data data that was read
/// @param count Number of bytes that was read.
/// @param data User-defined data
/// @param eof If the stream reached EOF.
/// @return number of bytes which were consumed
typedef size_t (*stream_read_cb)(RStream *stream, const char *read_data, size_t count, void *data,
                                 bool eof);

/// Type of function called when the Stream has information about a write
/// request.
///
/// @param stream The Stream instance
/// @param data User-defined data
/// @param status 0 on success, anything else indicates failure
typedef void (*stream_write_cb)(Stream *stream, void *data, int status);

typedef void (*stream_close_cb)(Stream *stream, void *data);

struct stream {
  bool closed;
  union {
    uv_pipe_t pipe;
    uv_tcp_t tcp;
    uv_idle_t idle;
#ifdef MSWIN
    uv_tty_t tty;
#endif
  } uv;
  uv_stream_t *uvstream;  ///< NULL when the stream is a file
  uv_file fd;    ///< When the stream is a file, this is its file descriptor
  int64_t fpos;  ///< When the stream is a file, this is the position in file
  void *cb_data;
  stream_close_cb close_cb, internal_close_cb;
  void *close_cb_data, *internal_data;
  size_t pending_reqs;
  MultiQueue *events;

  // only used for writing:
  stream_write_cb write_cb;
  size_t curmem;
  size_t maxmem;
};

struct rstream {
  Stream s;
  bool did_eof;
  bool want_read;
  bool pending_read;
  bool paused_full;
  char *buffer;  // ARENA_BLOCK_SIZE
  char *read_pos;
  char *write_pos;
  uv_buf_t uvbuf;
  stream_read_cb read_cb;
  size_t num_bytes;
};

#define ADDRESS_MAX_SIZE 256

typedef struct socket_watcher SocketWatcher;
typedef void (*socket_cb)(SocketWatcher *watcher, int result, void *data);
typedef void (*socket_close_cb)(SocketWatcher *watcher, void *data);

struct socket_watcher {
  // Pipe/socket path, or TCP address string
  char addr[ADDRESS_MAX_SIZE];
  // TCP server or unix socket (named pipe on Windows)
  union {
    struct {
      uv_tcp_t handle;
      struct addrinfo *addrinfo;
    } tcp;
    struct {
      uv_pipe_t handle;
    } pipe;
  } uv;
  uv_stream_t *stream;
  void *data;
  socket_cb cb;
  socket_close_cb close_cb;
  MultiQueue *events;
};

typedef enum {
  kProcTypeUv,
  kProcTypePty,
} ProcType;

/// OS process
typedef struct proc Proc;
typedef void (*proc_exit_cb)(Proc *proc, int status, void *data);
typedef void (*internal_proc_cb)(Proc *proc);

struct proc {
  ProcType type;
  Loop *loop;
  void *data;
  int pid, status, refcount;
  uint8_t exit_signal;  // Signal used when killing (on Windows).
  uint64_t stopped_time;  // proc_stop() timestamp
  const char *cwd;
  char **argv;
  const char *exepath;
  dict_T *env;
  Stream in;
  RStream out, err;
  /// Exit handler. If set, user must call proc_free().
  proc_exit_cb cb;
  internal_proc_cb internal_exit_cb, internal_close_cb;
  bool closed, detach, overlapped, fwd_err;
  MultiQueue *events;
};