Commit 993981a0 authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Keep track of bytes per callback

This allows to drop the requirement that the request itself is
responsible for keeping track of the number of bytes it has emitted via
`write_ptr` and the number of bytes that were actually written in
`write_cb`. The request queue now lets the request know how many bytes
have been written on its account, instead of asking for it.
parent 2ef4a5be
......@@ -126,6 +126,7 @@ int redis_request_queue_write_ptr(redis_request_queue *self, const char **dstbuf
assert(req->write_ptr);
req->write_ptr(req, &buf, &len, &done);
req->write_ptr_len += len;
if (done) {
req->write_ptr_done = 1;
......@@ -142,7 +143,7 @@ int redis_request_queue_write_ptr(redis_request_queue *self, const char **dstbuf
int redis_request_queue_write_cb(redis_request_queue *self, size_t len) {
ngx_queue_t *q = NULL;
redis_request *req = NULL;
int nwritten, done;
size_t nwritten;
while (len) {
if (ngx_queue_empty(&self->request_wait_write)) {
......@@ -151,7 +152,6 @@ int redis_request_queue_write_cb(redis_request_queue *self, size_t len) {
q = ngx_queue_last(&self->request_wait_write);
req = ngx_queue_data(q, redis_request, wq);
done = 0;
/* Add this request to `wait_read` if necessary */
if (ngx_queue_empty(&req->rq)) {
......@@ -162,23 +162,23 @@ int redis_request_queue_write_cb(redis_request_queue *self, size_t len) {
}
}
assert(req->write_cb);
nwritten = req->write_cb(req, len, &done);
/* Abort on error */
if (nwritten < 0) {
return nwritten;
nwritten = req->write_ptr_len - req->write_cb_len;
if (nwritten > len) {
nwritten = len;
}
assert((unsigned)nwritten <= len);
len -= nwritten;
assert(req->write_cb);
req->write_cb(req, nwritten);
req->write_cb_len += nwritten;
/* Remove this request from `wait_write` when done writing */
if (done) {
if (req->write_ptr_done && req->write_ptr_len == req->write_cb_len) {
ngx_queue_remove(q);
ngx_queue_init(q);
req->write_cb_done = 1;
}
len -= nwritten;
}
return 0;
......@@ -208,6 +208,7 @@ int redis_request_queue_read_cb(redis_request_queue *self, const char *buf, size
assert(req->read_cb);
req->read_cb(req, p, buf, nparsed, &done);
req->read_cb_len += nparsed;
/* Request cannot be done on partial reply */
assert(p || !done);
......
......@@ -29,14 +29,8 @@ typedef void (redis_request_write_ptr)(redis_request *self,
* Arguments:
* self the request as previously inserted in the queue
* n the number of bytes written
* done set to non-zero by the request when it has been written in full
*
* Return:
* the number of bytes (<= n) actually used
*/
typedef int (redis_request_write_cb)(redis_request *self,
int n,
int *done);
typedef void (redis_request_write_cb)(redis_request *self, int n);
/*
* Let the request know the wire-level data that was fed to the parser on its
......@@ -71,6 +65,9 @@ typedef void (redis_request_free)(redis_request *self);
unsigned write_ptr_done:1; \
unsigned write_cb_done:1; \
unsigned read_cb_done:1; \
size_t write_ptr_len; \
size_t write_cb_len; \
size_t read_cb_len; \
redis_request_write_ptr *write_ptr; \
redis_request_write_cb *write_cb; \
redis_request_read_cb *read_cb; \
......
......@@ -188,22 +188,9 @@ void t1_write_ptr(redis_request *_self, const char **buf, size_t *len, int *done
}
}
int t1_write_cb(redis_request *_self, int n, int *done) {
void t1_write_cb(redis_request *_self, int n) {
t1_redis_request *self = (t1_redis_request*)_self;
int to_write;
to_write = self->len - self->nwritten;
if (to_write > n) {
to_write = n;
}
self->nwritten += to_write;
if (self->nwritten == self->len) {
*done = 1;
}
return to_write;
self->nwritten += n;
}
void t1_read_cb(redis_request *_self, redis_protocol *p, const char *buf, size_t len, int *done) {
......
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