Compatibility with "Try to send VDP_END with the last bytes"

Ref varnish-cache c2d45aefb563bb105f524b67b84d20649ecb85a2
parent 8bc293ac
...@@ -176,13 +176,6 @@ vped_gzgz_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc) ...@@ -176,13 +176,6 @@ vped_gzgz_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc)
return (0); return (0);
} }
/*
* we removed a NULL VDP_FLUSH from _fini because in our code it goes to the
* _to_parent vdp on the same request, rather than one request up as in the
* original code.
*
* thus we need to flush at the end of each call
*/
static int v_matchproto_(vdp_bytes_f) static int v_matchproto_(vdp_bytes_f)
vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
const void *ptr, ssize_t len) const void *ptr, ssize_t len)
...@@ -192,6 +185,9 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -192,6 +185,9 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
ssize_t dl; ssize_t dl;
ssize_t l; ssize_t l;
// XXX would like to know which is the last
// segment sent to push FLUSH/END with it
CAST_OBJ_NOTNULL(foo, *priv, VPED_GZGZ_PRIV_MAGIC); CAST_OBJ_NOTNULL(foo, *priv, VPED_GZGZ_PRIV_MAGIC);
pp = ptr; pp = ptr;
if (len > 0) { if (len > 0) {
...@@ -212,7 +208,7 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -212,7 +208,7 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
if (dl > 0) { if (dl > 0) {
if (dl > len) if (dl > len)
dl = len; dl = len;
if (VDP_bytes(vdx, act, pp, dl)) if (VDP_bytes(vdx, VDP_NULL, pp, dl))
return(-1); return(-1);
foo->ll += dl; foo->ll += dl;
len -= dl; len -= dl;
...@@ -235,7 +231,7 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -235,7 +231,7 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
if (dl > 0) { if (dl > 0) {
if (dl > len) if (dl > len)
dl = len; dl = len;
if (VDP_bytes(vdx, act, pp, dl)) if (VDP_bytes(vdx, VDP_NULL, pp, dl))
return (-1); return (-1);
foo->ll += dl; foo->ll += dl;
len -= dl; len -= dl;
...@@ -318,7 +314,9 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -318,7 +314,9 @@ vped_gzgz_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
} }
} }
assert(len == 0); assert(len == 0);
return (VDP_bytes(vdx, VDP_FLUSH, NULL, 0)); if (act != VDP_END)
act = VDP_FLUSH;
return (VDP_bytes(vdx, act, NULL, 0));
} }
static int v_matchproto_(vdp_fini_f) static int v_matchproto_(vdp_fini_f)
......
...@@ -668,6 +668,22 @@ fini_data(struct vdp_ctx *vdx, struct node *node) ...@@ -668,6 +668,22 @@ fini_data(struct vdp_ctx *vdx, struct node *node)
* (unlocked) * (unlocked)
*/ */
static int
node_bytes(struct vdp_ctx *vdx, struct bytes_tree *tree,
const struct node *node, enum vdp_action act, const void *ptr, ssize_t sz)
{
if (node->is_end) {
AZ(tree->end_sent);
assert(tree->end == node);
tree->end_sent = 1;
act = VDP_END;
} else if (act == VDP_END) {
act = VDP_FLUSH;
}
return (VDP_bytes(vdx, act, ptr, sz));
}
static int static int
push_final(struct vdp_ctx *vdx, struct bytes_tree *tree, push_final(struct vdp_ctx *vdx, struct bytes_tree *tree,
struct node *node, const struct node *next) struct node *node, const struct node *next)
...@@ -690,6 +706,7 @@ push_final(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -690,6 +706,7 @@ push_final(struct vdp_ctx *vdx, struct bytes_tree *tree,
AZ(pthread_mutex_unlock(&node->final.fi_mtx)); AZ(pthread_mutex_unlock(&node->final.fi_mtx));
WRONG("ACT");
assert(node->final.fi_state == FI_DONE); assert(node->final.fi_state == FI_DONE);
return (tree->retval); return (tree->retval);
} }
...@@ -768,7 +785,6 @@ push_crc(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -768,7 +785,6 @@ push_crc(struct vdp_ctx *vdx, struct bytes_tree *tree,
assert(node->type == T_CRC); assert(node->type == T_CRC);
(void) vdx; (void) vdx;
(void) tree;
nex = node->parent; nex = node->parent;
CHECK_OBJ_NOTNULL(nex, NODE_MAGIC); CHECK_OBJ_NOTNULL(nex, NODE_MAGIC);
...@@ -797,8 +813,9 @@ push_crc(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -797,8 +813,9 @@ push_crc(struct vdp_ctx *vdx, struct bytes_tree *tree,
parent_gzip->l_crc += nex->nexus.gzip.l_crc; parent_gzip->l_crc += nex->nexus.gzip.l_crc;
} else { } else {
gzip_tailbuf(tailbuf, &nex->nexus.gzip); gzip_tailbuf(tailbuf, &nex->nexus.gzip);
return (VDP_bytes(nex->nexus.req->vdc, return (node_bytes(nex->nexus.req->vdc,
VDP_FLUSH, tailbuf, sizeof(tailbuf))); tree, node, VDP_FLUSH,
tailbuf, sizeof(tailbuf)));
} }
break; break;
default: default:
...@@ -818,8 +835,6 @@ push_data(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -818,8 +835,6 @@ push_data(struct vdp_ctx *vdx, struct bytes_tree *tree,
assert(node->type == T_DATA); assert(node->type == T_DATA);
(void) tree;
AN(node->parent); AN(node->parent);
assert(node->parent->type == T_NEXUS); assert(node->parent->type == T_NEXUS);
...@@ -839,7 +854,7 @@ push_data(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -839,7 +854,7 @@ push_data(struct vdp_ctx *vdx, struct bytes_tree *tree,
return (0); return (0);
vdx = node->parent->nexus.req->vdc; vdx = node->parent->nexus.req->vdc;
return (VDP_bytes(vdx, act, p, node->data.len)); return (node_bytes(vdx, tree, node, act, p, node->data.len));
} }
/* /*
...@@ -962,6 +977,8 @@ worklist_set_delivered(struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -962,6 +977,8 @@ worklist_set_delivered(struct vdp_ctx *vdx, struct bytes_tree *tree,
(tree)->front_owner = wrk; \ (tree)->front_owner = wrk; \
} while(0) } while(0)
#define set_end(tree, node) (tree)->end = node;
static void static void
worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree, worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree,
struct node_head *work) struct node_head *work)
...@@ -1049,6 +1066,8 @@ worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -1049,6 +1066,8 @@ worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree,
VSLdbg(vdx, "bytes_unpend: reached root"); VSLdbg(vdx, "bytes_unpend: reached root");
set_front(tree, tree->root, vdx->wrk); set_front(tree, tree->root, vdx->wrk);
if (tree->end != NULL)
tree->end->is_end = 1;
return; return;
} }
...@@ -1090,6 +1109,7 @@ worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree, ...@@ -1090,6 +1109,7 @@ worklist_unpend(const struct vdp_ctx *vdx, struct bytes_tree *tree,
VSTAILQ_INSERT_TAIL(work, node, unpend); VSTAILQ_INSERT_TAIL(work, node, unpend);
set_unpending(tree, node); set_unpending(tree, node);
set_end(tree, node);
// for more iterations, also accept UNPEND // for more iterations, also accept UNPEND
// for now, we use any // for now, we use any
......
...@@ -41,6 +41,9 @@ struct bytes_tree { ...@@ -41,6 +41,9 @@ struct bytes_tree {
struct node *front; struct node *front;
const struct worker *front_owner; const struct worker *front_owner;
const struct worker *unpend_owner; const struct worker *unpend_owner;
// candidate for last ever node
struct node *end;
int end_sent;
int npending; int npending;
int retval; int retval;
}; };
...@@ -184,6 +187,7 @@ struct node { ...@@ -184,6 +187,7 @@ struct node {
enum n_type type; enum n_type type;
enum n_state state; enum n_state state;
enum n_alloc allocator; enum n_alloc allocator;
unsigned is_end:1;
VSTAILQ_ENTRY(node) sibling; VSTAILQ_ENTRY(node) sibling;
VSTAILQ_ENTRY(node) unpend; VSTAILQ_ENTRY(node) unpend;
struct node *parent; struct node *parent;
......
...@@ -908,6 +908,9 @@ vdp_pesi_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -908,6 +908,9 @@ vdp_pesi_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
CHECK_OBJ_NOTNULL(vdx, VDP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vdx, VDP_CTX_MAGIC);
if (act == VDP_END)
act = VDP_FLUSH;
AN(priv); AN(priv);
CAST_OBJ_NOTNULL(pesi, *priv, PESI_MAGIC); CAST_OBJ_NOTNULL(pesi, *priv, PESI_MAGIC);
CHECK_OBJ_NOTNULL(pesi->pecx, PECX_MAGIC); CHECK_OBJ_NOTNULL(pesi->pecx, PECX_MAGIC);
...@@ -1125,6 +1128,8 @@ vdp_pesi_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv, ...@@ -1125,6 +1128,8 @@ vdp_pesi_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
&tree->tree_lock, 0)); &tree->tree_lock, 0));
tree_deliver(vdx, tree); tree_deliver(vdx, tree);
} }
if (! tree->end_sent)
(void) VDP_bytes(vdx, VDP_END, NULL, 0);
Lck_Unlock(&tree->tree_lock); Lck_Unlock(&tree->tree_lock);
return (tree->retval); return (tree->retval);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment