Exemple #1
0
static void
lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) {
	ns_lwdclientmgr_t *cm = ev->ev_arg;
	ns_lwdclient_t *client;

	REQUIRE(!SHUTTINGDOWN(cm));

	ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p",
			 task, cm);

	/*
	 * run through the idle list and free the clients there.  Idle
	 * clients do not have a recv running nor do they have any finds
	 * or similar running.
	 */
	LOCK(&cm->lock);
	client = ISC_LIST_HEAD(cm->idle);
	while (client != NULL) {
		ns_lwdclient_log(50, "destroying client %p, manager %p",
				 client, cm);
		ISC_LIST_UNLINK(cm->idle, client, link);
		isc_mem_put(cm->mctx, client, sizeof(*client));
		client = ISC_LIST_HEAD(cm->idle);
	}
	UNLOCK(&cm->lock);

	/*
	 * Cancel any pending I/O.
	 */
	isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL);

	/*
	 * Run through the running client list and kill off any finds
	 * in progress.
	 */
	LOCK(&cm->lock);
	client = ISC_LIST_HEAD(cm->running);
	while (client != NULL) {
		if (client->find != client->v4find
		    && client->find != client->v6find)
			dns_adb_cancelfind(client->find);
		if (client->v4find != NULL)
			dns_adb_cancelfind(client->v4find);
		if (client->v6find != NULL)
			dns_adb_cancelfind(client->v6find);
		client = ISC_LIST_NEXT(client, link);
	}

	cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN;

	UNLOCK(&cm->lock);

	isc_event_free(&ev);
}
Exemple #2
0
/*
 * This function will start a new recv() on a socket for this client manager.
 */
isc_result_t
ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) {
    ns_lwdclient_t *client;
    isc_result_t result;
    isc_region_t r;

    if (SHUTTINGDOWN(cm)) {
        lwdclientmgr_destroy(cm);
        return (ISC_R_SUCCESS);
    }

    /*
     * If a recv is already running, don't bother.
     */
    if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0)
        return (ISC_R_SUCCESS);

    /*
     * If we have no idle slots, just return success.
     */
    client = ISC_LIST_HEAD(cm->idle);
    if (client == NULL)
        return (ISC_R_SUCCESS);
    INSIST(NS_LWDCLIENT_ISIDLE(client));

    /*
     * Issue the recv.  If it fails, return that it did.
     */
    r.base = client->buffer;
    r.length = LWRES_RECVLENGTH;
    result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv,
                             client);
    if (result != ISC_R_SUCCESS)
        return (result);

    /*
     * Set the flag to say we've issued a recv() call.
     */
    cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING;

    /*
     * Remove the client from the idle list, and put it on the running
     * list.
     */
    NS_LWDCLIENT_SETRECV(client);
    ISC_LIST_UNLINK(cm->idle, client, link);
    ISC_LIST_APPEND(cm->running, client, link);

    return (ISC_R_SUCCESS);
}
Exemple #3
0
static void
lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) {
	ns_lwdclient_t *client;
	ns_lwreslistener_t *listener;

	LOCK(&cm->lock);
	if (!SHUTTINGDOWN(cm)) {
		UNLOCK(&cm->lock);
		return;
	}

	/*
	 * Run through the idle list and free the clients there.  Idle
	 * clients do not have a recv running nor do they have any finds
	 * or similar running.
	 */
	client = ISC_LIST_HEAD(cm->idle);
	while (client != NULL) {
		ns_lwdclient_log(50, "destroying client %p, manager %p",
				 client, cm);
		ISC_LIST_UNLINK(cm->idle, client, link);
		isc_mem_put(cm->mctx, client, sizeof(*client));
		client = ISC_LIST_HEAD(cm->idle);
	}

	if (!ISC_LIST_EMPTY(cm->running)) {
		UNLOCK(&cm->lock);
		return;
	}

	UNLOCK(&cm->lock);

	lwres_context_destroy(&cm->lwctx);
	cm->view = NULL;
	isc_socket_detach(&cm->sock);
	isc_task_detach(&cm->task);

	DESTROYLOCK(&cm->lock);

	listener = cm->listener;
	ns_lwreslistener_unlinkcm(listener, cm);
	ns_lwdclient_log(50, "destroying manager %p", cm);
	isc_mem_put(cm->mctx, cm, sizeof(*cm));
	ns_lwreslistener_detach(&listener);
}
Exemple #4
0
/*
 * This function will start a new recv() on a socket for this client manager.
 */
isc_result_t
ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) {
	ns_lwdclient_t *client;
	isc_result_t result;
	isc_region_t r;
	isc_boolean_t destroy = ISC_FALSE;


	LOCK(&cm->lock);
	if (SHUTTINGDOWN(cm)) {
		destroy = ISC_TRUE;
		result = ISC_R_SUCCESS;
		goto unlock;
	}

	/*
	 * If a recv is already running, don't bother.
	 */
	if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) {
		result = ISC_R_SUCCESS;
		goto unlock;
	}

	/*
	 * If we have no idle slots, just return success.
	 */
	client = ISC_LIST_HEAD(cm->idle);
	if (client == NULL) {
		result = ISC_R_SUCCESS;
		goto unlock;
	}

	INSIST(NS_LWDCLIENT_ISIDLE(client));

	/*
	 * Set the flag to say there is a recv pending.  If isc_socket_recv
	 * fails we will clear the flag otherwise it will be cleared by
	 * ns_lwdclient_recv.
	 */
	cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING;

	/*
	 * Issue the recv.  If it fails, return that it did.
	 */
	r.base = client->buffer;
	r.length = LWRES_RECVLENGTH;
	result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv,
				 client);
	if (result != ISC_R_SUCCESS) {
		cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING;
		goto unlock;
	}

	/*
	 * Remove the client from the idle list, and put it on the running
	 * list.
	 */
	NS_LWDCLIENT_SETRECV(client);
	ISC_LIST_UNLINK(cm->idle, client, link);
	ISC_LIST_APPEND(cm->running, client, link);

 unlock:
	UNLOCK(&cm->lock);

	if (destroy)
		lwdclientmgr_destroy(cm);

	return (result);
}