diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index dfaa4f6405f..e268949be35 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -32,3 +32,51 @@ */ #include "src/core/client_config/subchannel.h" + +#include + +struct grpc_subchannel { + gpr_refcount refs; +}; + +struct grpc_subchannel_call { + grpc_subchannel *subchannel; + gpr_refcount refs; +}; + +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) (((grpc_call_stack *)(call)) + 1) + +/* + * grpc_subchannel implementation + */ + +void grpc_subchannel_ref(grpc_subchannel *channel) { gpr_ref(&channel->refs); } + +void grpc_subchannel_unref(grpc_subchannel *channel) { + if (gpr_unref(&channel->refs)) { + gpr_free(channel); + } +} + +/* + * grpc_subchannel_call implementation + */ + +void grpc_subchannel_call_ref(grpc_subchannel_call *call) { + gpr_ref(&call->refs); +} + +void grpc_subchannel_call_unref(grpc_subchannel_call *call) { + if (gpr_unref(&call->refs)) { + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call)); + grpc_subchannel_unref(call->subchannel); + gpr_free(call); + } +} + +void grpc_subchannel_call_process_op(grpc_subchannel_call *call, + grpc_transport_stream_op *op) { + grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); + grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); + top_elem->filter->start_transport_stream_op(top_elem, op); +} diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 0c6c9b3e64d..4d2efef7fbd 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -60,10 +60,12 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *channel, grpc_connectivity_state *state, grpc_iomgr_closure *notify); -/** construct a call */ -grpc_subchannel_call *grpc_subchannel_create_call( - grpc_subchannel *subchannel, grpc_call_element *parent, - grpc_transport_stream_op *initial_op); +/** construct a call (asynchronously) */ +void grpc_subchannel_create_call(grpc_subchannel *subchannel, + grpc_call_element *parent, + grpc_transport_stream_op *initial_op, + grpc_subchannel_call **target, + grpc_iomgr_closure *notify); /** continue processing a transport op */ void grpc_subchannel_call_process_op(grpc_subchannel_call *subchannel_call,