static void *reader_thread (void *cache_ptr) { struct tags_cache *c = (struct tags_cache *)cache_ptr; int curr_queue = 0; /* index of the queue from where we will get the next request */ logit ("Tags reader thread started"); LOCK (c->mutex); while (!c->stop_reader_thread) { int i; char *request_file; int tags_sel = 0; /* find the queue with a request waiting, begin searching at * curr_queue: we want to get one request from each queue, * and then move to the next non-empty queue */ i = curr_queue; while (i < CLIENTS_MAX && request_queue_empty(&c->queues[i])) i++; if (i == CLIENTS_MAX) { i = 0; while (i < curr_queue && request_queue_empty(&c->queues[i])) i++; if (i == curr_queue) { debug ("All queues empty, waiting"); pthread_cond_wait (&c->request_cond, &c->mutex); continue; } } curr_queue = i; request_file = request_queue_pop (&c->queues[curr_queue], &tags_sel); UNLOCK (c->mutex); tags_cache_read_add (c, curr_queue, request_file, tags_sel); free (request_file); LOCK (c->mutex); if (++curr_queue == CLIENTS_MAX) curr_queue = 0; } UNLOCK (c->mutex); logit ("Exiting tags reader thread"); return NULL; }
/* * Submit an I/O request on a buffer. */ int submit_block(int rw, struct buffer *buf) { struct block_device *dev = get_device(buf->b_dev); struct request *req = make_request(rw, buf); buffer_lock(buf); if (request_queue_empty(dev)) dev->handle_request(dev, req); else list_add_tail(&req->chain, &dev->requests); return 0; }
/* * Block drivers call this function to signal completion of an I/O request. */ void block_request_completed(struct block_device *dev, struct request *req) { req->buf->b_flags |= BUF_UPTODATE; release_buffer(req->buf); buffer_unlock(req->buf); slab_free(request_cachep, req); if (request_queue_empty(dev)) return; req = list_first_entry(&dev->requests, struct request, chain); list_del(&req->chain); dev->handle_request(dev, req); }