예제 #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
파일: conn.c 프로젝트: geekmug/syncfs
static void *
np_conn_read_proc(void *a)
{
    int i, n, size, msize;
    Npsrv *srv;
    Npconn *conn;
    Nptrans *trans;
    Npreq *req;
    Npfcall *fc, *fc1;

    pthread_detach(pthread_self());
    conn = a;
    np_conn_incref(conn);
    srv = conn->srv;
    msize = conn->msize;
    fc = np_conn_new_incall(conn);
    n = 0;
    while (conn->trans && (i = np_trans_read(conn->trans, fc->pkt + n, msize - n)) > 0) {
        pthread_mutex_lock(&conn->lock);
        if (conn->resetting) {
            while(conn->resetting)
                pthread_cond_wait(&conn->resetdonecond, &conn->lock);
            n = 0;  /* discard all input */
            i = 0;
        }
        pthread_mutex_unlock(&conn->lock);
        n += i;

again:
        if (n < 4)
            continue;

        size = fc->pkt[0] | (fc->pkt[1]<<8) | (fc->pkt[2]<<16) | (fc->pkt[3]<<24);
        if (n < size)
            continue;

        if (!np_deserialize(fc, fc->pkt, conn->dotu))
            break;

        if (conn->srv->debuglevel) {
            fprintf(stderr, "<<< (%p) ", conn);
            np_printfcall(stderr, fc, conn->dotu);
            fprintf(stderr, "\n");
        }

        fc1 = np_conn_new_incall(conn);
        if (n > size)
            memmove(fc1->pkt, fc->pkt + size, n - size);
        n -= size;

        req = np_req_alloc(conn, fc);
        pthread_mutex_lock(&srv->lock);
        if (!conn->resetting)
            np_srv_add_req(srv, req);
        else
            np_req_unref(req);
        pthread_mutex_unlock(&srv->lock);
        fc = fc1;
        if (n > 0)
            goto again;

    }

    pthread_mutex_lock(&conn->lock);
    trans = conn->trans;
    conn->trans = NULL;
    np_conn_free_incall(conn, fc);
    pthread_mutex_unlock(&conn->lock);

    np_srv_remove_conn(conn->srv, conn);
    np_conn_reset(conn, 0, 0);

    if (trans)
        np_trans_destroy(trans);

    np_conn_decref(conn);
    return NULL;
}