blob: b51a041dc7132fb4897917f47237adf614e801d7 [file] [log] [blame]
Craig Tiller5dc3b302015-06-15 16:06:50 -07001/*
2 *
yang-g897925e2016-01-28 09:23:46 -08003 * Copyright 2015-2016, Google Inc.
Craig Tiller5dc3b302015-06-15 16:06:50 -07004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9533d042016-03-25 17:11:06 -070034#include "src/core/lib/transport/chttp2/internal.h"
Craig Tiller6459db42015-06-15 17:11:45 -070035
36#include <grpc/support/log.h>
37
Craig Tiller98505102015-06-16 11:33:15 -070038#define TRANSPORT_FROM_GLOBAL(tg) \
Craig Tiller6459db42015-06-15 17:11:45 -070039 ((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \
40 global)))
41
42#define STREAM_FROM_GLOBAL(sg) \
Craig Tiller98505102015-06-16 11:33:15 -070043 ((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, global)))
Craig Tiller6459db42015-06-15 17:11:45 -070044
Craig Tiller98505102015-06-16 11:33:15 -070045#define TRANSPORT_FROM_WRITING(tw) \
Craig Tiller6459db42015-06-15 17:11:45 -070046 ((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
47 writing)))
48
49#define STREAM_FROM_WRITING(sw) \
Craig Tiller98505102015-06-16 11:33:15 -070050 ((grpc_chttp2_stream *)((char *)(sw)-offsetof(grpc_chttp2_stream, writing)))
Craig Tiller6459db42015-06-15 17:11:45 -070051
Craig Tiller98505102015-06-16 11:33:15 -070052#define TRANSPORT_FROM_PARSING(tp) \
Craig Tiller6459db42015-06-15 17:11:45 -070053 ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
54 parsing)))
55
56#define STREAM_FROM_PARSING(sp) \
Craig Tiller98505102015-06-16 11:33:15 -070057 ((grpc_chttp2_stream *)((char *)(sp)-offsetof(grpc_chttp2_stream, parsing)))
Craig Tiller6459db42015-06-15 17:11:45 -070058
Craig Tiller5dc3b302015-06-15 16:06:50 -070059/* core list management */
60
61static int stream_list_empty(grpc_chttp2_transport *t,
62 grpc_chttp2_stream_list_id id) {
63 return t->lists[id].head == NULL;
64}
65
Craig Tiller98505102015-06-16 11:33:15 -070066static int stream_list_pop(grpc_chttp2_transport *t,
67 grpc_chttp2_stream **stream,
68 grpc_chttp2_stream_list_id id) {
Craig Tiller5dc3b302015-06-15 16:06:50 -070069 grpc_chttp2_stream *s = t->lists[id].head;
70 if (s) {
71 grpc_chttp2_stream *new_head = s->links[id].next;
72 GPR_ASSERT(s->included[id]);
73 if (new_head) {
74 t->lists[id].head = new_head;
75 new_head->links[id].prev = NULL;
76 } else {
77 t->lists[id].head = NULL;
78 t->lists[id].tail = NULL;
79 }
80 s->included[id] = 0;
81 }
Craig Tiller6459db42015-06-15 17:11:45 -070082 *stream = s;
83 return s != 0;
Craig Tiller5dc3b302015-06-15 16:06:50 -070084}
85
86static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
87 grpc_chttp2_stream_list_id id) {
Craig Tiller6459db42015-06-15 17:11:45 -070088 GPR_ASSERT(s->included[id]);
Craig Tiller5dc3b302015-06-15 16:06:50 -070089 s->included[id] = 0;
90 if (s->links[id].prev) {
91 s->links[id].prev->links[id].next = s->links[id].next;
92 } else {
93 GPR_ASSERT(t->lists[id].head == s);
94 t->lists[id].head = s->links[id].next;
95 }
96 if (s->links[id].next) {
97 s->links[id].next->links[id].prev = s->links[id].prev;
98 } else {
99 t->lists[id].tail = s->links[id].prev;
100 }
101}
102
Craig Tiller0cb803d2016-03-02 22:17:24 -0800103static bool stream_list_maybe_remove(grpc_chttp2_transport *t,
Craig Tiller285b8822015-06-17 15:58:13 -0700104 grpc_chttp2_stream *s,
105 grpc_chttp2_stream_list_id id) {
Craig Tiller759eb322015-06-16 22:41:18 -0700106 if (s->included[id]) {
107 stream_list_remove(t, s, id);
Craig Tiller0cb803d2016-03-02 22:17:24 -0800108 return true;
109 } else {
110 return false;
Craig Tiller759eb322015-06-16 22:41:18 -0700111 }
112}
113
Craig Tiller5dc3b302015-06-15 16:06:50 -0700114static void stream_list_add_tail(grpc_chttp2_transport *t,
115 grpc_chttp2_stream *s,
116 grpc_chttp2_stream_list_id id) {
117 grpc_chttp2_stream *old_tail;
118 GPR_ASSERT(!s->included[id]);
119 old_tail = t->lists[id].tail;
120 s->links[id].next = NULL;
121 s->links[id].prev = old_tail;
122 if (old_tail) {
123 old_tail->links[id].next = s;
124 } else {
Craig Tiller5dc3b302015-06-15 16:06:50 -0700125 t->lists[id].head = s;
126 }
127 t->lists[id].tail = s;
128 s->included[id] = 1;
129}
130
Craig Tiller0cb803d2016-03-02 22:17:24 -0800131static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
132 grpc_chttp2_stream_list_id id) {
Craig Tiller5dc3b302015-06-15 16:06:50 -0700133 if (s->included[id]) {
Craig Tiller0cb803d2016-03-02 22:17:24 -0800134 return false;
Craig Tiller5dc3b302015-06-15 16:06:50 -0700135 }
136 stream_list_add_tail(t, s, id);
Craig Tiller0cb803d2016-03-02 22:17:24 -0800137 return true;
Craig Tiller5dc3b302015-06-15 16:06:50 -0700138}
139
Craig Tiller6459db42015-06-15 17:11:45 -0700140/* wrappers for specializations */
141
Craig Tiller0cb803d2016-03-02 22:17:24 -0800142bool grpc_chttp2_list_add_writable_stream(
Craig Tiller6459db42015-06-15 17:11:45 -0700143 grpc_chttp2_transport_global *transport_global,
144 grpc_chttp2_stream_global *stream_global) {
Craig Tiller86316522015-07-15 11:35:07 -0700145 GPR_ASSERT(stream_global->id != 0);
Craig Tiller0cb803d2016-03-02 22:17:24 -0800146 return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
147 STREAM_FROM_GLOBAL(stream_global),
148 GRPC_CHTTP2_LIST_WRITABLE);
Craig Tiller6459db42015-06-15 17:11:45 -0700149}
150
151int grpc_chttp2_list_pop_writable_stream(
152 grpc_chttp2_transport_global *transport_global,
153 grpc_chttp2_transport_writing *transport_writing,
154 grpc_chttp2_stream_global **stream_global,
155 grpc_chttp2_stream_writing **stream_writing) {
156 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700157 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
158 GRPC_CHTTP2_LIST_WRITABLE);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700159 if (r != 0) {
160 *stream_global = &stream->global;
161 *stream_writing = &stream->writing;
162 }
Craig Tiller6459db42015-06-15 17:11:45 -0700163 return r;
164}
165
Craig Tiller0cb803d2016-03-02 22:17:24 -0800166bool grpc_chttp2_list_remove_writable_stream(
Craig Tiller994c2622015-07-23 14:00:58 -0700167 grpc_chttp2_transport_global *transport_global,
168 grpc_chttp2_stream_global *stream_global) {
Craig Tiller0cb803d2016-03-02 22:17:24 -0800169 return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
170 STREAM_FROM_GLOBAL(stream_global),
171 GRPC_CHTTP2_LIST_WRITABLE);
Craig Tiller994c2622015-07-23 14:00:58 -0700172}
173
Craig Tiller0cb803d2016-03-02 22:17:24 -0800174void grpc_chttp2_list_add_writing_stream(
Craig Tiller6459db42015-06-15 17:11:45 -0700175 grpc_chttp2_transport_writing *transport_writing,
176 grpc_chttp2_stream_writing *stream_writing) {
Craig Tiller0cb803d2016-03-02 22:17:24 -0800177 GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
178 STREAM_FROM_WRITING(stream_writing),
179 GRPC_CHTTP2_LIST_WRITING));
Craig Tiller6459db42015-06-15 17:11:45 -0700180}
181
182int grpc_chttp2_list_have_writing_streams(
183 grpc_chttp2_transport_writing *transport_writing) {
Craig Tillercdf52bc2015-06-16 13:00:27 -0700184 return !stream_list_empty(TRANSPORT_FROM_WRITING(transport_writing),
185 GRPC_CHTTP2_LIST_WRITING);
Craig Tiller6459db42015-06-15 17:11:45 -0700186}
187
188int grpc_chttp2_list_pop_writing_stream(
189 grpc_chttp2_transport_writing *transport_writing,
190 grpc_chttp2_stream_writing **stream_writing) {
191 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700192 int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream,
193 GRPC_CHTTP2_LIST_WRITING);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700194 if (r != 0) {
195 *stream_writing = &stream->writing;
196 }
Craig Tiller6459db42015-06-15 17:11:45 -0700197 return r;
198}
199
200void grpc_chttp2_list_add_written_stream(
201 grpc_chttp2_transport_writing *transport_writing,
202 grpc_chttp2_stream_writing *stream_writing) {
Craig Tiller98505102015-06-16 11:33:15 -0700203 stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
204 STREAM_FROM_WRITING(stream_writing),
205 GRPC_CHTTP2_LIST_WRITTEN);
Craig Tiller6459db42015-06-15 17:11:45 -0700206}
207
208int grpc_chttp2_list_pop_written_stream(
209 grpc_chttp2_transport_global *transport_global,
210 grpc_chttp2_transport_writing *transport_writing,
211 grpc_chttp2_stream_global **stream_global,
212 grpc_chttp2_stream_writing **stream_writing) {
213 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700214 int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream,
215 GRPC_CHTTP2_LIST_WRITTEN);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700216 if (r != 0) {
217 *stream_global = &stream->global;
218 *stream_writing = &stream->writing;
219 }
Craig Tiller6459db42015-06-15 17:11:45 -0700220 return r;
221}
222
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800223void grpc_chttp2_list_add_unannounced_incoming_window_available(
224 grpc_chttp2_transport_global *transport_global,
225 grpc_chttp2_stream_global *stream_global) {
226 GPR_ASSERT(stream_global->id != 0);
227 stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
228 STREAM_FROM_GLOBAL(stream_global),
229 GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE);
230}
231
232void grpc_chttp2_list_remove_unannounced_incoming_window_available(
233 grpc_chttp2_transport_global *transport_global,
234 grpc_chttp2_stream_global *stream_global) {
235 stream_list_maybe_remove(
236 TRANSPORT_FROM_GLOBAL(transport_global),
237 STREAM_FROM_GLOBAL(stream_global),
238 GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE);
239}
240
241int grpc_chttp2_list_pop_unannounced_incoming_window_available(
242 grpc_chttp2_transport_global *transport_global,
243 grpc_chttp2_transport_parsing *transport_parsing,
244 grpc_chttp2_stream_global **stream_global,
245 grpc_chttp2_stream_parsing **stream_parsing) {
246 grpc_chttp2_stream *stream;
247 int r =
248 stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
249 GRPC_CHTTP2_LIST_UNANNOUNCED_INCOMING_WINDOW_AVAILABLE);
250 if (r != 0) {
251 *stream_global = &stream->global;
252 *stream_parsing = &stream->parsing;
253 }
254 return r;
255}
256
Craig Tiller6459db42015-06-15 17:11:45 -0700257void grpc_chttp2_list_add_parsing_seen_stream(
258 grpc_chttp2_transport_parsing *transport_parsing,
259 grpc_chttp2_stream_parsing *stream_parsing) {
Craig Tiller98505102015-06-16 11:33:15 -0700260 stream_list_add(TRANSPORT_FROM_PARSING(transport_parsing),
261 STREAM_FROM_PARSING(stream_parsing),
262 GRPC_CHTTP2_LIST_PARSING_SEEN);
Craig Tiller6459db42015-06-15 17:11:45 -0700263}
264
265int grpc_chttp2_list_pop_parsing_seen_stream(
266 grpc_chttp2_transport_global *transport_global,
267 grpc_chttp2_transport_parsing *transport_parsing,
268 grpc_chttp2_stream_global **stream_global,
269 grpc_chttp2_stream_parsing **stream_parsing) {
270 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700271 int r = stream_list_pop(TRANSPORT_FROM_PARSING(transport_parsing), &stream,
272 GRPC_CHTTP2_LIST_PARSING_SEEN);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700273 if (r != 0) {
274 *stream_global = &stream->global;
275 *stream_parsing = &stream->parsing;
276 }
Craig Tiller6459db42015-06-15 17:11:45 -0700277 return r;
278}
279
280void grpc_chttp2_list_add_waiting_for_concurrency(
281 grpc_chttp2_transport_global *transport_global,
282 grpc_chttp2_stream_global *stream_global) {
Craig Tiller98505102015-06-16 11:33:15 -0700283 stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
284 STREAM_FROM_GLOBAL(stream_global),
285 GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
Craig Tiller6459db42015-06-15 17:11:45 -0700286}
287
288int grpc_chttp2_list_pop_waiting_for_concurrency(
289 grpc_chttp2_transport_global *transport_global,
290 grpc_chttp2_stream_global **stream_global) {
291 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700292 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
293 GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700294 if (r != 0) {
295 *stream_global = &stream->global;
296 }
Craig Tiller6459db42015-06-15 17:11:45 -0700297 return r;
298}
299
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800300void grpc_chttp2_list_add_check_read_ops(
301 grpc_chttp2_transport_global *transport_global,
302 grpc_chttp2_stream_global *stream_global) {
303 stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
304 STREAM_FROM_GLOBAL(stream_global),
305 GRPC_CHTTP2_LIST_CHECK_READ_OPS);
306}
307
308int grpc_chttp2_list_pop_check_read_ops(
309 grpc_chttp2_transport_global *transport_global,
310 grpc_chttp2_stream_global **stream_global) {
311 grpc_chttp2_stream *stream;
312 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
313 GRPC_CHTTP2_LIST_CHECK_READ_OPS);
314 if (r != 0) {
315 *stream_global = &stream->global;
316 }
317 return r;
318}
319
yang-g348f3a22016-01-27 16:17:32 -0800320void grpc_chttp2_list_add_writing_stalled_by_transport(
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800321 grpc_chttp2_transport_writing *transport_writing,
322 grpc_chttp2_stream_writing *stream_writing) {
yang-g276e32d2016-02-22 13:15:30 -0800323 grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing);
324 if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) {
325 GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled");
326 }
327 stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream,
yang-g348f3a22016-01-27 16:17:32 -0800328 GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT);
329}
330
331void grpc_chttp2_list_flush_writing_stalled_by_transport(
yang-g276e32d2016-02-22 13:15:30 -0800332 grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
yang-g55b1b592016-01-28 12:03:03 -0800333 bool is_window_available) {
yang-g348f3a22016-01-27 16:17:32 -0800334 grpc_chttp2_stream *stream;
335 grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing);
336 while (stream_list_pop(transport, &stream,
337 GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) {
yang-g55b1b592016-01-28 12:03:03 -0800338 if (is_window_available) {
Craig Tiller0cb803d2016-03-02 22:17:24 -0800339 grpc_chttp2_become_writable(&transport->global, &stream->global);
yang-g348f3a22016-01-27 16:17:32 -0800340 } else {
yang-g276e32d2016-02-22 13:15:30 -0800341 grpc_chttp2_list_add_stalled_by_transport(transport_writing,
342 &stream->writing);
yang-g348f3a22016-01-27 16:17:32 -0800343 }
yang-g276e32d2016-02-22 13:15:30 -0800344 GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global,
345 "chttp2_writing_stalled");
yang-g348f3a22016-01-27 16:17:32 -0800346 }
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800347}
348
yang-g276e32d2016-02-22 13:15:30 -0800349void grpc_chttp2_list_add_stalled_by_transport(
350 grpc_chttp2_transport_writing *transport_writing,
351 grpc_chttp2_stream_writing *stream_writing) {
352 stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
353 STREAM_FROM_WRITING(stream_writing),
354 GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
355}
356
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800357int grpc_chttp2_list_pop_stalled_by_transport(
358 grpc_chttp2_transport_global *transport_global,
359 grpc_chttp2_stream_global **stream_global) {
360 grpc_chttp2_stream *stream;
361 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
362 GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
363 if (r != 0) {
364 *stream_global = &stream->global;
365 }
366 return r;
367}
368
yang-g0db90322015-12-21 13:38:56 -0800369void grpc_chttp2_list_remove_stalled_by_transport(
370 grpc_chttp2_transport_global *transport_global,
371 grpc_chttp2_stream_global *stream_global) {
372 stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
373 STREAM_FROM_GLOBAL(stream_global),
374 GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
375}
376
Craig Tiller83fb0702015-06-16 21:13:07 -0700377void grpc_chttp2_list_add_closed_waiting_for_parsing(
Craig Tiller6459db42015-06-15 17:11:45 -0700378 grpc_chttp2_transport_global *transport_global,
379 grpc_chttp2_stream_global *stream_global) {
Craig Tiller98505102015-06-16 11:33:15 -0700380 stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
381 STREAM_FROM_GLOBAL(stream_global),
Craig Tiller83fb0702015-06-16 21:13:07 -0700382 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING);
Craig Tiller6459db42015-06-15 17:11:45 -0700383}
384
Craig Tiller83fb0702015-06-16 21:13:07 -0700385int grpc_chttp2_list_pop_closed_waiting_for_parsing(
Craig Tiller6459db42015-06-15 17:11:45 -0700386 grpc_chttp2_transport_global *transport_global,
387 grpc_chttp2_stream_global **stream_global) {
388 grpc_chttp2_stream *stream;
Craig Tiller98505102015-06-16 11:33:15 -0700389 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
Craig Tiller83fb0702015-06-16 21:13:07 -0700390 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING);
David Garcia Quintasc9ab6a02015-08-26 13:11:48 -0700391 if (r != 0) {
392 *stream_global = &stream->global;
393 }
Craig Tiller6459db42015-06-15 17:11:45 -0700394 return r;
395}
396
Craig Tillerabb2e3d2015-12-15 06:23:59 -0800397void grpc_chttp2_list_add_closed_waiting_for_writing(
398 grpc_chttp2_transport_global *transport_global,
399 grpc_chttp2_stream_global *stream_global) {
400 stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
401 STREAM_FROM_GLOBAL(stream_global),
402 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING);
403}
404
405int grpc_chttp2_list_pop_closed_waiting_for_writing(
406 grpc_chttp2_transport_global *transport_global,
407 grpc_chttp2_stream_global **stream_global) {
408 grpc_chttp2_stream *stream;
409 int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
410 GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_WRITING);
411 if (r != 0) {
412 *stream_global = &stream->global;
413 }
414 return r;
415}
416
Craig Tiller98505102015-06-16 11:33:15 -0700417void grpc_chttp2_register_stream(grpc_chttp2_transport *t,
418 grpc_chttp2_stream *s) {
Craig Tiller6459db42015-06-15 17:11:45 -0700419 stream_list_add_tail(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS);
420}
Craig Tiller1937b062015-06-16 08:47:38 -0700421
Craig Tiller9188d7a2015-07-05 12:44:37 -0700422int grpc_chttp2_unregister_stream(grpc_chttp2_transport *t,
Craig Tillerd6c98df2015-08-18 09:33:44 -0700423 grpc_chttp2_stream *s) {
Craig Tiller9188d7a2015-07-05 12:44:37 -0700424 stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS);
425 return stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS);
426}
427
428int grpc_chttp2_has_streams(grpc_chttp2_transport *t) {
429 return !stream_list_empty(t, GRPC_CHTTP2_LIST_ALL_STREAMS);
Craig Tiller6459db42015-06-15 17:11:45 -0700430}
Craig Tiller1937b062015-06-16 08:47:38 -0700431
Craig Tiller98505102015-06-16 11:33:15 -0700432void grpc_chttp2_for_all_streams(
433 grpc_chttp2_transport_global *transport_global, void *user_data,
434 void (*cb)(grpc_chttp2_transport_global *transport_global, void *user_data,
435 grpc_chttp2_stream_global *stream_global)) {
Craig Tiller1937b062015-06-16 08:47:38 -0700436 grpc_chttp2_stream *s;
Craig Tillerab630732015-06-25 11:20:01 -0700437 grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global);
438 for (s = t->lists[GRPC_CHTTP2_LIST_ALL_STREAMS].head; s != NULL;
439 s = s->links[GRPC_CHTTP2_LIST_ALL_STREAMS].next) {
Craig Tiller1937b062015-06-16 08:47:38 -0700440 cb(transport_global, user_data, &s->global);
441 }
442}