예제 #1
0
파일: mdeg.c 프로젝트: apprisi/illumos-gate
int
mdeg_unregister(mdeg_handle_t hdl)
{
	mdeg_clnt_t	*clnt;
	mdeg_handle_t	mdh;

	/* should never be called from a callback */
	ASSERT(!taskq_member(mdeg.taskq, curthread));

	rw_enter(&mdeg.rwlock, RW_WRITER);

	/* lookup the client */
	if ((clnt = mdeg_get_client(hdl)) == NULL) {
		rw_exit(&mdeg.rwlock);
		return (MDEG_FAILURE);
	}

	MDEG_DBG("client unregistered (0x%lx):\n", hdl);
	MDEG_DUMP_CLNT(clnt);

	/* save the handle to prevent reuse */
	mdh = clnt->hdl;
	bzero(clnt, sizeof (mdeg_clnt_t));

	clnt->hdl = mdh;

	mdeg.nclnts--;

	rw_exit(&mdeg.rwlock);

	return (MDEG_SUCCESS);
}
예제 #2
0
파일: mdeg.c 프로젝트: andreiw/polaris
/*
 * Register to receive an event notification when the system
 * machine description is updated.
 *
 * Passing NULL for the node specification parameter is valid
 * as long as the match specification is also NULL. In this
 * case, the client will receive a notification when the MD
 * has been updated, but the callback will not include any
 * information. The client is then responsible for obtaining
 * its own copy of the system MD and performing any processing
 * manually.
 */
int
mdeg_register(mdeg_node_spec_t *pspecp, mdeg_node_match_t *nmatchp,
    mdeg_cb_t cb, void *cb_arg, mdeg_handle_t *hdlp)
{
	mdeg_clnt_t	*clnt;

	/*
	 * If the RW lock is held, a client is calling
	 * register from its own callback.
	 */
	if (RW_LOCK_HELD(&mdeg.rwlock)) {
		MDEG_DBG("mdeg_register: rwlock already held\n");
		return (MDEG_FAILURE);
	}

	/* node spec and node match must both be valid, or both NULL */
	if (((pspecp != NULL) && (nmatchp == NULL)) ||
	    ((pspecp == NULL) && (nmatchp != NULL))) {
		MDEG_DBG("mdeg_register: invalid parameters\n");
		return (MDEG_FAILURE);
	}

	rw_enter(&mdeg.rwlock, RW_WRITER);

	clnt = mdeg_alloc_clnt();

	ASSERT(clnt);

	/*
	 * Fill in the rest of the data
	 */
	clnt->nmatch = nmatchp;
	clnt->pspec = pspecp;
	clnt->cb = cb;
	clnt->cb_arg = cb_arg;
	clnt->magic = MDEG_MAGIC;

	/* do this last */
	clnt->valid = B_TRUE;

	MDEG_DBG("client registered (0x%lx):\n", clnt->hdl);
	MDEG_DUMP_CLNT(clnt);

	mdeg.nclnts++;

	if (mdeg_notify_client_reg(clnt) != MDEG_SUCCESS) {
		bzero(clnt, sizeof (mdeg_clnt_t));
		rw_exit(&mdeg.rwlock);
		return (MDEG_FAILURE);
	}

	rw_exit(&mdeg.rwlock);

	*hdlp = clnt->hdl;

	return (MDEG_SUCCESS);
}
예제 #3
0
파일: mdeg.c 프로젝트: andreiw/polaris
int
mdeg_unregister(mdeg_handle_t hdl)
{
	mdeg_clnt_t	*clnt;
	mdeg_handle_t	mdh;

	/*
	 * If the RW lock is held, a client is calling
	 * unregister from its own callback.
	 */
	if (RW_LOCK_HELD(&mdeg.rwlock)) {
		MDEG_DBG("mdeg_unregister: rwlock already held\n");
		return (MDEG_FAILURE);
	}

	/* lookup the client */
	if ((clnt = mdeg_get_client(hdl)) == NULL) {
		return (MDEG_FAILURE);
	}

	rw_enter(&mdeg.rwlock, RW_WRITER);

	MDEG_DBG("client unregistered (0x%lx):\n", hdl);
	MDEG_DUMP_CLNT(clnt);

	/* save the handle to prevent reuse */
	mdh = clnt->hdl;
	bzero(clnt, sizeof (mdeg_clnt_t));

	clnt->hdl = mdh;

	mdeg.nclnts--;

	rw_exit(&mdeg.rwlock);

	return (MDEG_SUCCESS);
}