From 88272ecb5fbee5629d9674f02e4e8645601e340d Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 1 Dec 2006 21:36:22 +0100 Subject: [PATCH] Simplified the asio module. --- lib/asio.c | 55 ++++++++++++++++++++---------------------------------- lib/asio.h | 12 +++++------- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/lib/asio.c b/lib/asio.c index f1996aae..ab024bed 100644 --- a/lib/asio.c +++ b/lib/asio.c @@ -49,8 +49,8 @@ asio_init_queue(struct asio_queue *q) DBG("ASIO: New queue %p", q); ASSERT(q->buffer_size); q->allocated_requests = 0; - q->allocated_writebacks = 0; q->running_requests = 0; + q->running_writebacks = 0; clist_init(&q->idle_list); clist_init(&q->done_list); work_queue_init(&asio_wpool, &q->queue); @@ -61,8 +61,8 @@ asio_cleanup_queue(struct asio_queue *q) { DBG("ASIO: Removing queue %p", q); ASSERT(!q->running_requests); + ASSERT(!q->running_writebacks); ASSERT(!q->allocated_requests); - ASSERT(!q->allocated_writebacks); ASSERT(clist_empty(&q->done_list)); struct asio_request *r; @@ -95,6 +95,10 @@ asio_get(struct asio_queue *q) DBG("ASIO: Got %p", r); } r->op = ASIO_FREE; + r->fd = -1; + r->len = 0; + r->status = -1; + r->returned_errno = -1; return r; } @@ -112,7 +116,7 @@ asio_raw_wait(struct asio_queue *q) die("Asynchronous write to fd %d failed: %s", r->fd, strerror(r->returned_errno)); if (r->status != (int)r->len) die("Asynchronous write to fd %d wrote only %d bytes out of %d", r->fd, r->status, r->len); - q->allocated_writebacks--; + q->running_writebacks--; asio_put(r); } else @@ -120,36 +124,6 @@ asio_raw_wait(struct asio_queue *q) return 1; } -struct asio_request * -asio_get_writeback(struct asio_queue *q) -{ - while (q->allocated_writebacks >= q->max_writebacks) - { - DBG("ASIO: Waiting for free writeback request"); - if (!asio_raw_wait(q)) - ASSERT(0); - } - q->allocated_writebacks++; - struct asio_request *r = asio_get(q); - r->op = ASIO_WRITE_BACK; - return r; -} - -void -asio_turn_to_writeback(struct asio_request *r) -{ - struct asio_queue *q = r->queue; - ASSERT(r->op != ASIO_WRITE_BACK); - while (q->allocated_writebacks >= q->max_writebacks) - { - DBG("ASIO: Waiting for free writeback request"); - if (!asio_raw_wait(q)) - ASSERT(0); - } - q->allocated_writebacks++; - r->op = ASIO_WRITE_BACK; -} - static void asio_handler(struct worker_thread *t UNUSED, struct work *w) { @@ -180,6 +154,16 @@ asio_submit(struct asio_request *r) struct asio_queue *q = r->queue; DBG("ASIO: Submitting %p on queue %p", r, q); ASSERT(r->op != ASIO_FREE); + if (r->op == ASIO_WRITE_BACK) + { + while (q->running_writebacks >= q->max_writebacks) + { + DBG("ASIO: Waiting for free writebacks"); + if (!asio_raw_wait(q)) + ASSERT(0); + } + q->running_writebacks++; + } q->running_requests++; r->work.go = asio_handler; r->work.returned = NULL; @@ -247,7 +231,7 @@ int main(void) asio_put(r); break; } - asio_turn_to_writeback(r); + r->op = ASIO_WRITE_BACK; r->fd = 1; r->len = r->status; asio_submit(r); @@ -267,7 +251,8 @@ int main(void) for (uns i=0; i<10; i++) { - r = asio_get_writeback(&q); + r = asio_get(&q); + r->op = ASIO_WRITE_BACK; r->fd = 1; r->len = 1; r->buffer[0] = 'A' + i; diff --git a/lib/asio.h b/lib/asio.h index 31c1f5ac..61e5ebd5 100644 --- a/lib/asio.h +++ b/lib/asio.h @@ -19,8 +19,8 @@ struct asio_queue { uns buffer_size; // How large buffers do we use [user-settable] uns max_writebacks; // Maximum number of writeback requests active [user-settable] uns allocated_requests; - uns allocated_writebacks; - uns running_requests; + uns running_requests; // Total number of running requests + uns running_writebacks; // How many of them are writebacks clist idle_list; // Recycled requests waiting for get clist done_list; // Finished requests struct work_queue queue; @@ -30,7 +30,7 @@ enum asio_op { ASIO_FREE, ASIO_READ, ASIO_WRITE, - ASIO_WRITE_BACK, // Write with no success notification + ASIO_WRITE_BACK, // Background write with no success notification }; struct asio_request { @@ -46,10 +46,8 @@ struct asio_request { void asio_init_queue(struct asio_queue *q); // Initialize a new queue void asio_cleanup_queue(struct asio_queue *q); -struct asio_request *asio_get(struct asio_queue *q); // Get an empty request (not for writeback) -struct asio_request *asio_get_writeback(struct asio_queue *q); // Get an empty writeback request -void asio_turn_to_writeback(struct asio_request *r); // Convert a request allocated as non-writeback to writeback -void asio_submit(struct asio_request *r); // Submit the request +struct asio_request *asio_get(struct asio_queue *q); // Get an empty request +void asio_submit(struct asio_request *r); // Submit the request (can block if too many writebacks) struct asio_request *asio_wait(struct asio_queue *q); // Wait for the first finished request, NULL if no more void asio_put(struct asio_request *r); // Return a finished request for recycling void asio_sync(struct asio_queue *q); // Wait until all requests are finished -- 2.39.5