Пример #1
0
static Npfcall*
np_flush(Npreq *req, Npfcall *tc)
{
	u16 oldtag;
	Npreq *creq;
	Npconn *conn;
	Npfcall *ret;

	ret = NULL;
	conn = req->conn;
	oldtag = tc->oldtag;
	pthread_mutex_lock(&conn->srv->lock);
	// check pending requests
	for(creq = conn->srv->reqs_first; creq != NULL; creq = creq->next) {
		if (creq->conn==conn && creq->tag==oldtag) {
			np_srv_remove_request(conn->srv, creq);
			ret = np_create_rflush();
			creq = NULL;
			goto done;
		}
	}

	// check working requests
	creq = conn->srv->workreqs;
	while (creq != NULL) {
		if (creq->conn==conn && creq->tag==oldtag) {
			req->flushreq = creq->flushreq;
			creq->flushreq = req;
			goto done;
		}
		creq = creq->next;
	}

	// if not found, return Rflush
	if (!creq)
		ret = np_create_rflush();

done:
	pthread_mutex_unlock(&conn->srv->lock);

	// if working request found, try to flush it
	if (creq && req->conn->srv->flush)
		(*req->conn->srv->flush)(creq);

	return ret;
}
Пример #2
0
void
np_respond(Npreq *req, Npfcall *rc)
{
	Npsrv *srv;
	Npreq *freq, *freq1;
	Npconn *conn;

	req->rcall = rc;
	srv = req->conn->srv;

	pthread_mutex_lock(&srv->lock);
	if (req->prev)
		req->prev->next = req->next;
	else
		srv->workreqs = req->next;

	if (req->next)
		req->next->prev = req->prev;

	/* remove the flush requests from the working queue */
	for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) {
		if (freq->prev)
			freq->prev->next = freq->next;
		else
			srv->workreqs = freq->next;

		if (freq->next)
			freq->next->prev = freq->prev;
	}
	pthread_mutex_unlock(&srv->lock);

	if (req->rcall) {
		if (req->rcall->id==Rread && req->fid->type&Qtdir)
			req->fid->diroffset = req->tcall->offset + req->rcall->count;

		np_set_tag(req->rcall, req->tag);
		np_conn_send_fcall(req->conn, req->rcall);
	}

	freq = req->flushreq;
	while (freq != NULL) {
		rc = np_create_rflush();
		np_set_tag(rc, freq->tag);
		conn = freq->conn;
		np_conn_send_fcall(freq->conn, rc);
		freq1 = freq->flushreq;
		np_conn_free_rcall(freq->conn, freq->tcall);
		reqfree(freq);
		freq = freq1;
	}

	np_conn_free_rcall(req->conn, req->tcall);
	reqfree(req);
}
Пример #3
0
static void
test_rflush (void)
{
    Npfcall *fc, *fc2;

    if (!(fc = np_create_rflush ()))
        msg_exit ("out of memory in %s", __FUNCTION__); 
    fc2 = _rcv_buf (fc, P9_RFLUSH, __FUNCTION__);

    free (fc);
    free (fc2);
}
Пример #4
0
static void
np_respond(Nptpool *tp, Npreq *req, Npfcall *rc)
{
	Npreq *freq;

	xpthread_mutex_lock(&req->lock);
	if (req->responded) {
		free(rc);
		xpthread_mutex_unlock(&req->lock);
		np_req_unref(req);
		return;
	}
	req->responded = 1;
	xpthread_mutex_unlock(&req->lock);

	xpthread_mutex_lock(&tp->lock);
	np_srv_remove_workreq(tp, req);
	for(freq = req->flushreq; freq != NULL; freq = freq->flushreq)
		np_srv_remove_workreq(tp, freq);
	xpthread_mutex_unlock(&tp->lock);

	xpthread_mutex_lock(&req->lock);
	req->rcall = rc;
	if (req->rcall) {
		np_set_tag(req->rcall, req->tag);
		if (req->fid != NULL) {
			np_fid_decref(req->fid);
			req->fid = NULL;
		}
		np_conn_respond(req);		
	}

	for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) {
		xpthread_mutex_lock(&freq->lock);
		freq->rcall = np_create_rflush();
		np_set_tag(freq->rcall, freq->tag);
		np_conn_respond(freq);
		xpthread_mutex_unlock(&freq->lock);
		np_req_unref(freq);
	}
	xpthread_mutex_unlock(&req->lock);
	np_req_unref(req);
}
Пример #5
0
static void
test_rflush (void)
{
    Npfcall *fc, *fc2;
    char buf[STATIC_RFLUSH_SIZE];

    if (!(fc = np_create_rflush ()))
        msg_exit ("out of memory in %s", __FUNCTION__); 
    fc2 = _rcv_buf (fc, P9_RFLUSH, __FUNCTION__);

    free (fc);
    free (fc2);

    if (!(fc = np_create_rflush_static (buf, sizeof(buf))))
        msg_exit ("out of memory in %s", __FUNCTION__); 
    fc2 = _rcv_buf (fc, P9_RFLUSH, __FUNCTION__);

    free (fc2);
}
Пример #6
0
Npfcall*
np_flush(Npreq *req, Npfcall *tc)
{
	u16 oldtag = tc->u.tflush.oldtag;
	Npreq *creq = NULL;
	Npconn *conn = req->conn;
	Npfcall *ret = NULL;
	Nptpool *tp;

	xpthread_mutex_lock(&conn->srv->lock);
	// check pending requests
	for (tp = conn->srv->tpool; tp != NULL; tp = tp->next) {
		xpthread_mutex_lock(&tp->lock);
		for(creq = tp->reqs_first; creq != NULL; creq = creq->next) {
			if (creq->conn==conn && creq->tag==oldtag) {
				np_srv_remove_req(tp, creq);
				xpthread_mutex_lock(&creq->lock);
				np_conn_respond(creq); /* doesn't send anything */
				xpthread_mutex_unlock(&creq->lock);
				np_req_unref(creq);
				ret = np_create_rflush();
				creq = NULL;
				xpthread_mutex_unlock(&tp->lock);
				goto done;
			}
		}
		xpthread_mutex_unlock(&tp->lock);
	}

	// check working requests
	for (tp = conn->srv->tpool; tp != NULL; tp = tp->next) {
		xpthread_mutex_lock(&tp->lock);
		creq = tp->workreqs;
		while (creq != NULL) {
			if (creq->conn==conn && creq->tag==oldtag) {
				np_req_ref(creq);
				xpthread_mutex_lock(&creq->lock);
				req->flushreq = creq->flushreq;
				creq->flushreq = req;
				xpthread_mutex_unlock(&creq->lock);
				xpthread_mutex_unlock(&tp->lock);
				goto done;
			}
			creq = creq->next;
		}
		xpthread_mutex_unlock(&tp->lock);
	}

	// if not found, return P9_RFLUSH
	if (!creq)
		ret = np_create_rflush();

done:
	xpthread_mutex_unlock(&conn->srv->lock);

	// if working request found, try to flush it
	if (creq && req->conn->srv->flush) {
		(*req->conn->srv->flush)(creq);
		np_req_unref(creq);
	}

	return ret;
}