Beispiel #1
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);
}
Beispiel #2
0
/* Allocate a new Npfcall to "receive" raw data from fc->pkt.
 */
static Npfcall *
_rcv_buf (Npfcall *fc, int type, const char *fun)
{
    Npfcall *fc2;
    char s[256];

    printf ("%s(%d): %d\n", fun, type, fc->size);
    np_set_tag (fc, 42);

    /* see conn.c:np_conn_new_incall () */
    if (!(fc2 = malloc (sizeof (*fc2) + TEST_MSIZE)))
        msg_exit ("out of memory");
    fc2->pkt = (u8 *)fc2 + sizeof (*fc2);

    /* see conn.c::np_conn_read_proc */
    memcpy (fc2->pkt, fc->pkt, fc->size);
    if (!np_deserialize (fc2))
        msg_exit ("np_deserialize error in %s", fun);

    /* check a few things */
    if (fc->type != type)
        msg_exit ("incorrect type in %s", fun);
    if (fc->size != fc2->size)
        msg_exit ("size mismatch in %s", fun);
    if (fc->type != fc2->type)
        msg_exit ("type mismatch in %s", fun);

    np_snprintfcall (s, sizeof (s), fc);
    printf ("%s\n", s);

    return fc2;
}
Beispiel #3
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);
}
Beispiel #4
0
static int
npc_rpc(Npcfsys *fs, Npfcall *tc, Npfcall **rcp)
{
	Npfcall *rc = NULL;
	u16 tag = P9_NOTAG;
	int n, ret = -1;

	if (!fs->trans) {
		np_uerror(ECONNABORTED);
		goto done;
	}
	if (tc->type != P9_TVERSION)
		tag = npc_get_id(fs->tagpool);
	np_set_tag(tc, tag);

	xpthread_mutex_lock(&fs->lock);
	n = np_trans_send (fs->trans, tc);
	if (n >= 0)
		n = np_trans_recv(fs->trans, &rc, fs->msize);
	xpthread_mutex_unlock(&fs->lock);
	if (n < 0)
		goto done;
	if (rc == NULL) {
		np_uerror (EPROTO); /* premature EOF */
		goto done;
	}
	if (tc->tag != rc->tag) {
		np_uerror (EPROTO); /* unmatched response */
		goto done;
	}
	if (rc->type == P9_RLERROR) {
		np_uerror (rc->u.rlerror.ecode);
		goto done;
	}
	*rcp = rc;
	ret = 0;
done:
	if (tag != P9_NOTAG)
		npc_put_id(fs->tagpool, tag);
	if (ret < 0 && rc != NULL)
		free (rc);
	return ret;
}
Beispiel #5
0
static void
np_respond(Nptpool *tp, Npreq *req, Npfcall *rc)
{
	xpthread_mutex_lock(&tp->srv->lock);
	np_srv_remove_workreq(tp, req);
	xpthread_mutex_unlock(&tp->srv->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);		
	}

	xpthread_mutex_unlock(&req->lock);
	np_req_unref(req);
}
Beispiel #6
0
static void
_flush_series (Npcfsys *fs, Npcfid *root)
{
    Npfcall *rc = NULL, *tc = NULL, *ac = NULL;
    u16 tag, flushtag;
    int n, i;
    struct sigaction sa;

    assert (fs->trans != NULL);

    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sa.sa_handler = _alarm_clock;
    if (sigaction (SIGALRM, &sa, NULL) < 0)
        err_exit ("sigaction");

    /* write 100 tversions */
    for (i = 0; i < 100; i++) {
        if (!(tc = np_create_tversion (fs->msize, "9P2000.L")))
            msg_exit ("out of memory");
        flushtag = tag = npc_get_id(fs->tagpool);
        np_set_tag(tc, tag);
        n = np_trans_write(fs->trans, tc->pkt, tc->size);
        if (n < 0)
            errn_exit (np_rerror (), "np_trans_write");
        if (n != tc->size)
            msg_exit ("np_trans_write came up unexpectedly short");
        //msg ("sent tversion tag %d", tc->tag);
        free(tc);
    }
    msg ("sent 100 tversions");

    /* flush the most recent */
    if (!(ac = np_create_tflush (flushtag)))
        msg_exit ("out of memory");
    tag = npc_get_id(fs->tagpool);
    np_set_tag(ac, tag);
    n = np_trans_write(fs->trans, ac->pkt, ac->size);
    if (n < 0)
        errn_exit (np_rerror (), "np_trans_write");
    if (n != ac->size)
        msg_exit ("np_trans_write came up unexpectedly short");
    //msg ("sent tflush tag %d (flushing tag %d)", ac->tag, flushtag);
    free (ac);
    msg ("sent 1 tflush");
        
    /* receive up to 101 responses with 1s timeout */
    for (i = 0; i < 101; i++) {
        if (!(rc = malloc(sizeof(*rc) + fs->msize)))
            msg_exit ("out of memory");
        rc->pkt = (u8*)rc + sizeof(*rc);
        alarm (1);
        n = np_trans_read(fs->trans, rc->pkt, fs->msize);
        if (n < 0) {
            if (errno == EINTR)
                break;
            errn_exit (np_rerror (), "np_trans_read");
        }
        alarm (0);
        if (n == 0)
            msg_exit ("np_trans_read: unexpected EOF");
        if (!np_deserialize (rc, rc->pkt))
            msg_exit ("failed to deserialize response in one go");
        //msg ("received tag %d", rc->tag);
        free(rc);
        //npc_put_id(fs->tagpool, rc->tag);
    }
    if (i == 100 || i == 101)
        msg ("received 100/101 respones");
    else 
        msg ("received %d responses", i);
}