|
|
@ -31,6 +31,34 @@ |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "src/core/transport/chttp2/internal.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <grpc/support/log.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define TRANSPORT_FROM_GLOBAL(tg) \ |
|
|
|
|
|
|
|
((grpc_chttp2_transport *)((char *)(tg)-offsetof(grpc_chttp2_transport, \
|
|
|
|
|
|
|
|
global))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define STREAM_FROM_GLOBAL(sg) \ |
|
|
|
|
|
|
|
((grpc_chttp2_stream *)((char *)(sg)-offsetof(grpc_chttp2_stream, \
|
|
|
|
|
|
|
|
global))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define TRANSPORT_FROM_WRITING(tw) \ |
|
|
|
|
|
|
|
((grpc_chttp2_transport *)((char *)(tw)-offsetof(grpc_chttp2_transport, \
|
|
|
|
|
|
|
|
writing))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define STREAM_FROM_WRITING(sw) \ |
|
|
|
|
|
|
|
((grpc_chttp2_stream *)((char *)(sw)-offsetof(grpc_chttp2_stream, \
|
|
|
|
|
|
|
|
writing))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define TRANSPORT_FROM_PARSING(tp) \ |
|
|
|
|
|
|
|
((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \
|
|
|
|
|
|
|
|
parsing))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define STREAM_FROM_PARSING(sp) \ |
|
|
|
|
|
|
|
((grpc_chttp2_stream *)((char *)(sp)-offsetof(grpc_chttp2_stream, \
|
|
|
|
|
|
|
|
parsing))) |
|
|
|
|
|
|
|
|
|
|
|
/* core list management */ |
|
|
|
/* core list management */ |
|
|
|
|
|
|
|
|
|
|
|
static int stream_list_empty(grpc_chttp2_transport *t, |
|
|
|
static int stream_list_empty(grpc_chttp2_transport *t, |
|
|
@ -38,8 +66,8 @@ static int stream_list_empty(grpc_chttp2_transport *t, |
|
|
|
return t->lists[id].head == NULL; |
|
|
|
return t->lists[id].head == NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static grpc_chttp2_stream *stream_list_remove_head( |
|
|
|
static int stream_list_pop( |
|
|
|
grpc_chttp2_transport *t, grpc_chttp2_stream_list_id id) { |
|
|
|
grpc_chttp2_transport *t, grpc_chttp2_stream **stream, grpc_chttp2_stream_list_id id) { |
|
|
|
grpc_chttp2_stream *s = t->lists[id].head; |
|
|
|
grpc_chttp2_stream *s = t->lists[id].head; |
|
|
|
if (s) { |
|
|
|
if (s) { |
|
|
|
grpc_chttp2_stream *new_head = s->links[id].next; |
|
|
|
grpc_chttp2_stream *new_head = s->links[id].next; |
|
|
@ -53,12 +81,13 @@ static grpc_chttp2_stream *stream_list_remove_head( |
|
|
|
} |
|
|
|
} |
|
|
|
s->included[id] = 0; |
|
|
|
s->included[id] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
return s; |
|
|
|
*stream = s; |
|
|
|
|
|
|
|
return s != 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
|
|
|
static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
|
|
|
grpc_chttp2_stream_list_id id) { |
|
|
|
grpc_chttp2_stream_list_id id) { |
|
|
|
if (!s->included[id]) return; |
|
|
|
GPR_ASSERT(s->included[id]); |
|
|
|
s->included[id] = 0; |
|
|
|
s->included[id] = 0; |
|
|
|
if (s->links[id].prev) { |
|
|
|
if (s->links[id].prev) { |
|
|
|
s->links[id].prev->links[id].next = s->links[id].next; |
|
|
|
s->links[id].prev->links[id].next = s->links[id].next; |
|
|
@ -91,7 +120,7 @@ static void stream_list_add_tail(grpc_chttp2_transport *t, |
|
|
|
s->included[id] = 1; |
|
|
|
s->included[id] = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void stream_list_join(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
|
|
|
static void stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
|
|
|
grpc_chttp2_stream_list_id id) { |
|
|
|
grpc_chttp2_stream_list_id id) { |
|
|
|
if (s->included[id]) { |
|
|
|
if (s->included[id]) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -99,3 +128,141 @@ static void stream_list_join(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
|
|
|
stream_list_add_tail(t, s, id); |
|
|
|
stream_list_add_tail(t, s, id); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* wrappers for specializations */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_writable_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_writable_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_writing **stream_writing) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, GRPC_CHTTP2_LIST_WRITABLE); |
|
|
|
|
|
|
|
*stream_global = &stream->global; |
|
|
|
|
|
|
|
*stream_writing = &stream->writing; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_writing_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_writing *stream_writing) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), STREAM_FROM_WRITING(stream_writing), GRPC_CHTTP2_LIST_WRITING); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_have_writing_streams( |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing) { |
|
|
|
|
|
|
|
return stream_list_empty(TRANSPORT_FROM_WRITING(transport_writing), GRPC_CHTTP2_LIST_WRITING); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_writing_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_writing **stream_writing) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, GRPC_CHTTP2_LIST_WRITING); |
|
|
|
|
|
|
|
*stream_writing = &stream->writing; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_written_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_writing *stream_writing) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), STREAM_FROM_WRITING(stream_writing), GRPC_CHTTP2_LIST_WRITTEN); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_written_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_transport_writing *transport_writing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_writing **stream_writing) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_WRITING(transport_writing), &stream, GRPC_CHTTP2_LIST_WRITTEN); |
|
|
|
|
|
|
|
*stream_writing = &stream->writing; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_writable_window_update_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_writable_window_update_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE); |
|
|
|
|
|
|
|
*stream_global = &stream->global; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_parsing_seen_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_parsing *transport_parsing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_parsing *stream_parsing) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_PARSING(transport_parsing), STREAM_FROM_PARSING(stream_parsing), GRPC_CHTTP2_LIST_PARSING_SEEN); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_parsing_seen_stream( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_transport_parsing *transport_parsing, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_parsing **stream_parsing) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_PARSING(transport_parsing), &stream, GRPC_CHTTP2_LIST_PARSING_SEEN); |
|
|
|
|
|
|
|
*stream_global = &stream->global; |
|
|
|
|
|
|
|
*stream_parsing = &stream->parsing; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_waiting_for_concurrency( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_waiting_for_concurrency( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY); |
|
|
|
|
|
|
|
*stream_global = &stream->global; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_cancelled_waiting_for_parsing( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_CANCELLED_WAITING_FOR_PARSING); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int grpc_chttp2_list_pop_cancelled_waiting_for_parsing( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global **stream_global) { |
|
|
|
|
|
|
|
grpc_chttp2_stream *stream; |
|
|
|
|
|
|
|
int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream, GRPC_CHTTP2_LIST_CANCELLED_WAITING_FOR_PARSING); |
|
|
|
|
|
|
|
*stream_global = &stream->global; |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_read_write_state_changed( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_READ_WRITE_STATE_CHANGED); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_list_add_incoming_window_state_changed( |
|
|
|
|
|
|
|
grpc_chttp2_transport_global *transport_global, |
|
|
|
|
|
|
|
grpc_chttp2_stream_global *stream_global) { |
|
|
|
|
|
|
|
stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_INCOMING_WINDOW_STATE_CHANGED); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_register_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { |
|
|
|
|
|
|
|
stream_list_add_tail(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void grpc_chttp2_unregister_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *s) { |
|
|
|
|
|
|
|
stream_list_remove(t, s, GRPC_CHTTP2_LIST_ALL_STREAMS);
|
|
|
|
|
|
|
|
} |
|
|
|