h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
{
	uint32_t wu;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	ASSERT_RXTHR(h2);
	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);

	if (h2->rxf_len != 4)
		return (H2CE_FRAME_SIZE_ERROR);
	wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
	if (wu == 0)
		return (H2SE_PROTOCOL_ERROR);
	if (r2 == NULL)
		return (0);
	Lck_Lock(&h2->sess->mtx);
	r2->t_window += wu;
	if (r2 == h2->req0)
		AZ(pthread_cond_broadcast(h2->winupd_cond));
	else if (r2->cond != NULL)
		AZ(pthread_cond_signal(r2->cond));
	Lck_Unlock(&h2->sess->mtx);
	if (r2->t_window >= (1LL << 31))
		return (H2SE_FLOW_CONTROL_ERROR);
	return (0);
}
h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
{
	uint32_t wu;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	ASSERT_RXTHR(h2);
	CHECK_OBJ_ORNULL(r2, H2_REQ_MAGIC);

	if (h2->rxf_len != 4)
		return (H2CE_FRAME_SIZE_ERROR);
	wu = vbe32dec(h2->rxf_data) & ~(1LU<<31);
	if (wu == 0)
		return (H2SE_PROTOCOL_ERROR);
	if (r2 == NULL)
		return (0);
	Lck_Lock(&h2->sess->mtx);
	r2->t_window += wu;
	if (r2 == h2->req0)
		AZ(pthread_cond_broadcast(h2->winupd_cond));
	else if (r2->cond != NULL)
		AZ(pthread_cond_signal(r2->cond));
	Lck_Unlock(&h2->sess->mtx);
	if (r2->t_window >= (1LL << 31))
		return (H2SE_FLOW_CONTROL_ERROR);
	return (0);
}