示例#1
0
void
np_conn_respond(Npreq *req)
{
	int n;
	Npconn *conn;
	Nptrans *trans;
	Npfcall *rc;

	trans = NULL;
	conn = req->conn;
	rc = req->rcall;
	pthread_mutex_lock(&conn->lock);
	if (conn->trans && !conn->resetting && rc) {
		if (conn->srv->debuglevel) {
			print_timestamp(stderr);
			fprintf(stderr, " >>> (%p) ", conn);
			np_printfcall(stderr, rc, conn->dotu);
			if ( req->tcall->encryptor )
				fprintf(stderr, " (encrypted)");
			fprintf(stderr, "\n");
		}

		if ( req->tcall->encryptor ) {	
			/* Request was encrypted => encrypt also the response */
			rc->encryptor = req->tcall->encryptor;
			rc = np_encrypt_fcall(rc);
			req->rcall = rc;
		}

		n = np_trans_write(conn->trans, rc->pkt, rc->size);
		if (n <= 0) {
			trans = conn->trans;
			conn->trans = NULL;
		}
	}

	np_conn_free_incall(req->conn, req->tcall);
	free(req->rcall);
	req->tcall = NULL;
	req->rcall = NULL;
	pthread_mutex_unlock(&conn->lock);

	if (conn->resetting) {
		pthread_mutex_lock(&conn->srv->lock);
		pthread_cond_broadcast(&conn->resetcond);
		pthread_mutex_unlock(&conn->srv->lock);
	}

	if (trans)
		np_trans_destroy(trans); /* np_conn_read_proc will take care of resetting */
}
示例#2
0
文件: conn.c 项目: nuxlli/npfs
void
np_conn_respond(Npreq *req)
{
	int n, send;
	Npconn *conn;
	Nptrans *trans;
	Npfcall *rc;

	trans = NULL;
	conn = req->conn;
	rc = req->rcall;
	if (!rc)
		goto done;

	pthread_mutex_lock(&conn->lock);
	send = conn->trans && !conn->resetting;
	pthread_mutex_unlock(&conn->lock);

	if (send) {
		pthread_mutex_lock(&conn->wlock);
		if (conn->srv->debuglevel) {
			fprintf(stderr, ">>> (%p) ", conn);
			np_printfcall(stderr, rc, conn->dotu);
			fprintf(stderr, "\n");
		}
		n = np_trans_write(conn->trans, rc->pkt, rc->size);
		pthread_mutex_unlock(&conn->wlock);

		if (n <= 0) {
			pthread_mutex_lock(&conn->lock);
			trans = conn->trans;
			conn->trans = NULL;
			pthread_mutex_unlock(&conn->lock);
		}
	}

done:
	np_conn_free_incall(req->conn, req->tcall, 1);
	free(req->rcall);
	req->tcall = NULL;
	req->rcall = NULL;

	if (conn->resetting) {
		pthread_mutex_lock(&conn->srv->lock);
		pthread_cond_broadcast(&conn->resetcond);
		pthread_mutex_unlock(&conn->srv->lock);
	}

	if (trans)
		np_trans_destroy(trans); /* np_conn_read_proc will take care of resetting */
}
示例#3
0
/* Called by srv workers to transmit req->rcall->pkt.
 */
void
np_conn_respond(Npreq *req)
{
	int n, send;
	Npconn *conn = req->conn;
	Npsrv *srv = conn->srv;
	Npfcall *rc = req->rcall;
	Nptrans *trans = NULL;

	if (!rc)
		goto done;

	xpthread_mutex_lock(&conn->lock);
	send = conn->trans && !conn->resetting;
	xpthread_mutex_unlock(&conn->lock);

	if (send) {
		if ((srv->flags & SRV_FLAGS_DEBUG_9PTRACE))
			_debug_trace (srv, rc);
		xpthread_mutex_lock(&conn->wlock);
		n = np_trans_write(conn->trans, rc->pkt, rc->size);
		conn->reqs_out++;
		xpthread_mutex_unlock(&conn->wlock);
		if (n <= 0) { /* write error */
			xpthread_mutex_lock(&conn->lock);
			trans = conn->trans;
			conn->trans = NULL;
			xpthread_mutex_unlock(&conn->lock);
		}
	}

done:
	_free_npfcall(req->tcall);
	free(req->rcall);
	req->tcall = NULL;
	req->rcall = NULL;

	if (conn->resetting) {
		xpthread_mutex_lock(&conn->srv->lock);
		xpthread_cond_broadcast(&conn->resetcond);
		xpthread_mutex_unlock(&conn->srv->lock);
	}

	if (trans) /* np_conn_read_proc will take care of resetting */
		np_trans_destroy(trans); 
}
示例#4
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);
}