Example #1
0
/*
 * 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);
	}
Example #2
0
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;
	}
Example #3
0
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);
    }
}