/* * Read a single request into the userspace filesystem's buffer. This * function waits until a request is available, then removes it from * the pending list and copies request data to userspace buffer. If * no reply is needed (FORGET) or request has been aborted or there * was an error during the copying then it's finished by calling * request_end(). Otherwise add it to the processing list, and set * the 'sent' flag. */ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, unsigned long nr_segs, loff_t *off) { int err; struct fuse_req *req; struct fuse_in *in; struct fuse_copy_state cs; unsigned reqsize; struct fuse_conn *fc = fuse_get_conn(file); if (!fc) return -EPERM; restart: spin_lock(&fc->lock); err = -EAGAIN; if ((file->f_flags & O_NONBLOCK) && fc->connected && !request_pending(fc)) goto err_unlock; request_wait(fc); err = -ENODEV; if (!fc->connected) goto err_unlock; err = -ERESTARTSYS; if (!request_pending(fc)) goto err_unlock; if (!list_empty(&fc->interrupts)) { req = list_entry(fc->interrupts.next, struct fuse_req, intr_entry); return fuse_read_interrupt(fc, req, iov, nr_segs); }
static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes, loff_t *off) { ssize_t ret; struct fuse_conn *fc = DEV_FC(file); struct fuse_req *req = NULL; spin_lock(&fuse_lock); request_wait(fc); if(fc->sb != NULL && !list_empty(&fc->pending)) { req = list_entry(fc->pending.next, struct fuse_req, list); list_del_init(&req->list); req->locked = 1; }
int main() { { // create the context context_t c; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "//" << std::endl; std::cout << "// STARTING CALLBACKS DEMO" << std::endl; std::cout << "//" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl; // queue up a bunch of requests for (int i = COUNT.load(std::memory_order_relaxed); i > 0; i--) { c.create_request(i, my_callback); } // wait until we've received callbacks from all of the requests for (;;) { int count = COUNT.load(std::memory_order_consume); if (! count > 0) { break; } std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cout << std::endl << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "//" << std::endl; std::cout << "// STARTING FUTURE/PROMISE DEMO" << std::endl; std::cout << "//" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl; for (int i = 0; i < 10; ++i) { context_t::caller_request_t* request = c.create_request(i); request->wait(); std::cout << "future/promise returned from the wait condition"; std::cout << ", future/promise is ready: " << (request->ready() ? "TRUE" : "FALSE"); std::cout << ", future/promise result is: " << request->result << std::endl; // when using the future/promise it's the job of the caller to delete // the request freeing up all memory allocated for that request. // this is done because the library doesn't know how long the caller // will need to keep the request around delete request; } } { std::cout << std::endl << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "//" << std::endl; std::cout << "// STARTING OPAQUE STRUCTURES/POINTERS DEMO" << std::endl; std::cout << "//" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl; void* c = new_context(); for (int i = 0; i < 10; ++i) { void* request = context_create_request(c, i); request_wait(request); std::cout << "future/promise returned from the wait condition"; std::cout << ", future/promise is ready: " << (request_ready(request) ? "TRUE" : "FALSE"); std::cout << ", future/promise result is: " << request_result(request) << std::endl; // when using the future/promise it's the job of the caller to delete // the request freeing up all memory allocated for that request. // this is done because the library doesn't know how long the caller // will need to keep the request around free_request(request); } free_context(c); } }