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
173
174
175
176
177
178
179
180
181
|
#ifndef INCLUDE_UV_LINK_H_
#define INCLUDE_UV_LINK_H_
#include "uv.h"
typedef struct uv_link_s uv_link_t;
typedef struct uv_link_methods_s uv_link_methods_t;
typedef struct uv_link_source_s uv_link_source_t;
typedef struct uv_link_observer_s uv_link_observer_t;
typedef void (*uv_link_alloc_cb)(uv_link_t* link,
size_t suggested_size,
uv_buf_t* buf);
typedef void (*uv_link_read_cb)(uv_link_t* link,
ssize_t nread,
const uv_buf_t* buf);
typedef void (*uv_link_write_cb)(uv_link_t* source, int status, void* arg);
typedef void (*uv_link_shutdown_cb)(uv_link_t* source, int status, void* arg);
typedef void (*uv_link_close_cb)(uv_link_t* source);
struct uv_link_methods_s {
int (*read_start)(uv_link_t* link);
int (*read_stop)(uv_link_t* link);
int (*write)(uv_link_t* link,
uv_link_t* source,
const uv_buf_t bufs[],
unsigned int nbufs,
uv_stream_t* send_handle,
uv_link_write_cb cb,
void* arg);
int (*try_write)(uv_link_t* link,
const uv_buf_t bufs[],
unsigned int nbufs);
int (*shutdown)(uv_link_t* link,
uv_link_t* source,
uv_link_shutdown_cb cb,
void* arg);
void (*close)(uv_link_t* link, uv_link_t* source, uv_link_close_cb cb);
/* Overriding callbacks */
uv_link_alloc_cb alloc_cb_override;
uv_link_read_cb read_cb_override;
};
#define UV_LINK_FIELDS \
uv_link_t* parent; \
uv_link_t* child; \
\
uv_link_alloc_cb alloc_cb; \
uv_link_read_cb read_cb; \
\
void* data; \
\
/* Read-only after assigning initial values */ \
\
/* Sort of virtual table */ \
uv_link_methods_t const* methods; \
\
/* Private, used for chain/unchain */ \
uv_link_alloc_cb saved_alloc_cb; \
uv_link_read_cb saved_read_cb; \
\
/* Private, used for close */ \
int close_depth; \
int close_waiting; \
uv_link_close_cb saved_close_cb; \
uv_link_t* pending_close_source;
struct uv_link_s {
UV_LINK_FIELDS
};
UV_EXTERN int uv_link_init(uv_link_t* link, uv_link_methods_t const* methods);
UV_EXTERN void uv_link_close(uv_link_t* link, uv_link_close_cb cb);
UV_EXTERN int uv_link_chain(uv_link_t* from, uv_link_t* to);
UV_EXTERN int uv_link_unchain(uv_link_t* from, uv_link_t* to);
/* Use this to invoke parent link's methods */
UV_EXTERN void uv_link_propagate_alloc_cb(uv_link_t* link,
size_t suggested_size,
uv_buf_t* buf);
UV_EXTERN void uv_link_propagate_read_cb(uv_link_t* link,
ssize_t nread,
const uv_buf_t* buf);
int uv_link_propagate_write(uv_link_t* link, uv_link_t* source,
const uv_buf_t bufs[], unsigned int nbufs,
uv_stream_t* send_handle,
uv_link_write_cb cb, void* arg);
int uv_link_propagate_shutdown(uv_link_t* link,
uv_link_t* source,
uv_link_shutdown_cb cb,
void* arg);
void uv_link_propagate_close(uv_link_t* link, uv_link_t* source,
uv_link_close_cb cb);
/* Use this to invoke methods of `link` */
int uv_link_read_start(uv_link_t* link);
int uv_link_read_stop(uv_link_t* link);
static int uv_link_write(uv_link_t* link, const uv_buf_t bufs[],
unsigned int nbufs, uv_stream_t* send_handle,
uv_link_write_cb cb, void* arg) {
return uv_link_propagate_write(link, link, bufs, nbufs, send_handle, cb, arg);
}
int uv_link_try_write(uv_link_t* link,
const uv_buf_t bufs[],
unsigned int nbufs);
static int uv_link_shutdown(uv_link_t* link, uv_link_shutdown_cb cb,
void* arg) {
return uv_link_propagate_shutdown(link, link, cb, arg);
}
/* Link Source */
struct uv_link_source_s {
/* inherits(uv_link_source_t, uv_link_t) */
UV_LINK_FIELDS
uv_stream_t* stream;
uv_link_close_cb close_cb;
uv_link_t* close_source;
};
/* NOTE: uses `stream->data` field */
UV_EXTERN int uv_link_source_init(uv_link_source_t* source,
uv_stream_t* stream);
/* Link Observer */
struct uv_link_observer_s {
/* inherits(uv_link_observer_t, uv_link_t) */
UV_LINK_FIELDS
/* This will be called, even if the ones in `link` will be overwritten */
void (*observer_read_cb)(uv_link_observer_t* observer,
ssize_t nread,
const uv_buf_t* buf);
};
UV_EXTERN int uv_link_observer_init(uv_link_observer_t* observer);
/* Default callbacks */
int uv_link_default_read_start(uv_link_t* link);
int uv_link_default_read_stop(uv_link_t* link);
int uv_link_default_write(uv_link_t* link,
uv_link_t* source,
const uv_buf_t bufs[],
unsigned int nbufs,
uv_stream_t* send_handle,
uv_link_write_cb cb,
void* arg);
int uv_link_default_try_write(uv_link_t* link,
const uv_buf_t bufs[],
unsigned int nbufs);
int uv_link_default_shutdown(uv_link_t* link,
uv_link_t* source,
uv_link_shutdown_cb cb,
void* arg);
void uv_link_default_close(uv_link_t* link, uv_link_t* source,
uv_link_close_cb cb);
void uv_link_default_alloc_cb(uv_link_t* link,
size_t suggested_size,
uv_buf_t* buf);
void uv_link_default_read_cb(uv_link_t* link,
ssize_t nread,
const uv_buf_t* buf);
#endif /* INCLUDE_UV_LINK_H_ */
|