Esempio n. 1
0
File: conn.c Progetto: EuroCorp/diod
static void
np_conn_destroy(Npconn *conn)
{
    int n;

    NP_ASSERT(conn != NULL);
    NP_ASSERT(conn->refcount == 0);
    /* issue 83: remove from srv->conns before destroying fidpool
     */
    np_srv_remove_conn (conn->srv, conn);
    if (conn->fidpool) {
        if ((n = np_fidpool_destroy(conn->fidpool)) > 0) {
            np_logmsg (conn->srv, "%s: connection closed with "
                       "%d unclunked fids",
                       np_conn_get_client_id (conn), n);
        }
        conn->fidpool = NULL;
    }
    if (conn->trans) {
        np_trans_destroy (conn->trans);
        conn->trans = NULL;
    }
    pthread_mutex_destroy(&conn->lock);
    pthread_mutex_destroy(&conn->wlock);
    pthread_cond_destroy(&conn->refcond);

    free(conn);
}
Esempio n. 2
0
void
np_conn_decref(Npconn *conn)
{
    Npfcall *fc, *fc1;

    pthread_mutex_lock(&conn->lock);
    assert(conn->refcount > 0);
    conn->refcount--;
    if (conn->refcount) {
        pthread_mutex_unlock(&conn->lock);
        return;
    }

    if (conn->fidpool) {
        np_fidpool_destroy(conn->fidpool);
        conn->fidpool = NULL;
    }

    fc = conn->freerclist;
    conn->freerclist = NULL;
    while (fc != NULL) {
        fc1 = fc->next;
        free(fc);
        fc = fc1;
    }

    pthread_mutex_unlock(&conn->lock);
    pthread_mutex_destroy(&conn->lock);
    free(conn);
}
Esempio n. 3
0
Npconn*
np_conn_create(Npsrv *srv, Nptrans *trans, char *client_id)
{
	Npconn *conn;
	int err;

	if (!(conn = malloc(sizeof(*conn)))) {
		errno = ENOMEM;
		return NULL;
	}
	pthread_mutex_init(&conn->lock, NULL);
	pthread_mutex_init(&conn->wlock, NULL);
	pthread_cond_init(&conn->resetcond, NULL);

	conn->refcount = 0;
	conn->resetting = 0;
	conn->srv = srv;
	conn->msize = srv->msize;
	conn->shutdown = 0;
	conn->reqs_in = 0;
	conn->reqs_out = 0;
	if (!(conn->fidpool = np_fidpool_create())) {
		free (conn);
		errno = ENOMEM;
		return NULL;
	}
	snprintf(conn->client_id, sizeof(conn->client_id), "%s", client_id);
	conn->authuser = P9_NONUNAME;

	conn->trans = trans;
	conn->aux = NULL;
	np_srv_add_conn(srv, conn);

	err = pthread_create(&conn->rthread, NULL, np_conn_read_proc, conn);
	if (err != 0) {
		np_srv_remove_conn (srv, conn);
		np_fidpool_destroy(conn->fidpool);
		free (conn);
		errno = err;
		return NULL;
	}

	return conn;
}
Esempio n. 4
0
/* Clear all state associated with conn out of the srv.
 * No more I/O is possible; we have disassociated the trans from the conn.
 */
static void
np_conn_reset(Npconn *conn)
{
	int reqslen;
	Npsrv *srv;
	Npreq *preqs, **reqs;

	xpthread_mutex_lock(&conn->lock);
	conn->resetting = 1;
	xpthread_mutex_unlock(&conn->lock);
	
	xpthread_mutex_lock(&conn->srv->lock);
	srv = conn->srv;
	preqs = _get_waiting_reqs (conn);
	if (_get_working_reqs (conn, &reqs, &reqslen) < 0) {
		xpthread_mutex_unlock(&conn->srv->lock);
		goto error;
	}
	xpthread_mutex_unlock(&conn->srv->lock);

	_flush_waiting_reqs (preqs);
	_flush_working_reqs (reqs, reqslen);

	xpthread_mutex_lock(&srv->lock);
	while (_count_working_reqs (conn, 1) > 0)
		xpthread_cond_wait(&conn->resetcond, &srv->lock);
	xpthread_mutex_unlock(&srv->lock);

	xpthread_mutex_lock(&conn->lock);
	if (conn->fidpool) {
		np_fidpool_destroy(conn->fidpool);
		conn->fidpool = NULL;
	}
	conn->resetting = 0;
	xpthread_mutex_unlock(&conn->lock);

	_free_working_reqs (reqs, reqslen);
	return;
error:
	return;
}
Esempio n. 5
0
void
np_conn_decref(Npconn *conn)
{
	xpthread_mutex_lock(&conn->lock);
	assert(conn->refcount > 0);
	conn->refcount--;
	if (conn->refcount) {
		xpthread_mutex_unlock(&conn->lock);
		return;
	}

	if (conn->fidpool) {
		np_fidpool_destroy(conn->fidpool);
		conn->fidpool = NULL;
	}
	
	xpthread_mutex_unlock(&conn->lock);
	pthread_mutex_destroy(&conn->lock);
	pthread_cond_destroy(&conn->resetcond);
	free(conn);
}
Esempio n. 6
0
void
np_conn_reset(Npconn *conn, u32 msize, int dotu)
{
    int i, n;
    Npsrv *srv;
    Npreq *req, *req1, *preqs, **reqs;
    Npfcall *fc, *fc1;

    pthread_mutex_lock(&conn->lock);
    conn->resetting = 1;
    pthread_mutex_unlock(&conn->lock);

    pthread_mutex_lock(&conn->srv->lock);
    srv = conn->srv;
    // first flush all outstanding requests
    preqs = NULL;
    req = srv->reqs_first;
    while (req != NULL) {
        req1 = req->next;
        if (req->conn == conn) {
            np_srv_remove_req(srv, req);
            req->next = preqs;
            preqs = req;
        }
        req = req1;
    }

    // then flush all working requests
    n = 0;
    req = conn->srv->workreqs;
    while (req != NULL) {
        if (req->conn == conn && (msize==0 || req->tcall->type != Tversion))
            n++;

        req = req->next;
    }

    reqs = malloc(n * sizeof(Npreq *));
    n = 0;
    req = conn->srv->workreqs;
    while (req != NULL) {
        if (req->conn == conn && (msize==0 || req->tcall->type != Tversion))
            reqs[n++] = np_req_ref(req);
        req = req->next;
    }
    pthread_mutex_unlock(&conn->srv->lock);

    req = preqs;
    while (req != NULL) {
        req1 = req->next;
        np_conn_respond(req);
        np_req_unref(req);
        req = req1;
    }

    for(i = 0; i < n; i++) {
        req = reqs[i];
        if (req->conn->srv->flush)
            (*req->conn->srv->flush)(req);
    }

    /* wait until all working requests finish */
/*
    pthread_mutex_lock(&conn->lock);
    while (1) {
        for(i = 0; i < n; i++)
            if (!reqs[i]->responded)
                break;

        if (i >= n)
            break;

        pthread_cond_wait(&conn->resetcond, &conn->lock);
    }
*/
    pthread_mutex_lock(&srv->lock);
    while (1) {
        for(req = srv->workreqs; req != NULL; req = req->next)
            if (req->conn == conn && (msize==0 || req->tcall->type != Tversion))
                break;

        if (req == NULL)
            break;

        while(conn->resetting)
            pthread_cond_wait(&conn->resetcond, &srv->lock);
    }
    pthread_mutex_unlock(&srv->lock);

    /* free old pool of fcalls */
    fc = conn->freerclist;
    conn->freerclist = NULL;
    while (fc != NULL) {
        fc1 = fc->next;
        free(fc);
        fc = fc1;
    }

    if (conn->fidpool) {
        np_fidpool_destroy(conn->fidpool);
        conn->fidpool = NULL;
    }

    if (msize) {
        conn->dotu = dotu;
        conn->resetting = 0;
        conn->fidpool = np_fidpool_create();
        pthread_cond_broadcast(&conn->resetdonecond);
    }
    conn->resetting = 0;
    pthread_mutex_unlock(&conn->lock);

    /* free the working requests */
    for(i = 0; i < n; i++)
        np_req_unref(reqs[i]);
    free(reqs);
}