Commit c12cb8fe authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

util: add method for setting fd_group's wrapper



A wrapper is a function that is executed when an event is triggered
prior to executing the callback associated with that event.  It can be
used to perform tasks common to all fds in an fd_group, without having
to control the code that adds the fds.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ia6e29d430dad220497aa2858529662a3934c6c52
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25464


Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Reviewed-by: default avatarAnkit Kumar <ankit.kumar@samsung.com>
Community-CI: Mellanox Build Bot
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 43c35d80
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -245,6 +245,22 @@ struct epoll_event;
 */
int spdk_fd_group_get_epoll_event(struct epoll_event *event);

typedef int (*spdk_fd_group_wrapper_fn)(void *wrapper_ctx, spdk_fd_fn cb_fn, void *cb_ctx);

/**
 * Set a wrapper function to be called when an epoll(7) event is received.  The callback associated
 * with that event is passed to the wrapper, which is responsible for executing it.  Only one
 * wrapper can be assigned to an fd_group at a time.
 *
 * \param fgrp fd group.
 * \param cb_fn Wrapper callback.
 * \param cb_ctx Wrapper callback's context.
 *
 * \return 0 on success, negative errno otherwise.
 */
int spdk_fd_group_set_wrapper(struct spdk_fd_group *fgrp, spdk_fd_group_wrapper_fn cb_fn,
			      void *cb_ctx);

#ifdef __cplusplus
}
#endif
+38 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ struct event_handler {
	int				fd;
	uint32_t			events;
	uint32_t			fd_type;
	struct spdk_fd_group		*owner;
	char				name[SPDK_MAX_EVENT_NAME_LEN + 1];
};

@@ -51,6 +52,8 @@ struct spdk_fd_group {
	uint32_t num_fds;

	struct spdk_fd_group *parent;
	spdk_fd_group_wrapper_fn wrapper_fn;
	void *wrapper_arg;

	/* interrupt sources list */
	TAILQ_HEAD(, event_handler) event_handlers;
@@ -286,6 +289,10 @@ spdk_fd_group_nest(struct spdk_fd_group *parent, struct spdk_fd_group *child)
		return -EINVAL;
	}

	if (parent->wrapper_fn != NULL) {
		return -EINVAL;
	}

	/* The epoll instance at the root holds all fds, so either the parent is the root or it
	 * doesn't hold any fds.
	 */
@@ -424,6 +431,7 @@ spdk_fd_group_add_ext(struct spdk_fd_group *fgrp, int efd, spdk_fd_fn fn, void *
	ehdlr->state = EVENT_HANDLER_STATE_WAITING;
	ehdlr->events = eh_opts.events;
	ehdlr->fd_type = eh_opts.fd_type;
	ehdlr->owner = fgrp;
	snprintf(ehdlr->name, sizeof(ehdlr->name), "%s", name);

	root = fd_group_get_root(fgrp);
@@ -583,6 +591,7 @@ spdk_fd_group_destroy(struct spdk_fd_group *fgrp)
int
spdk_fd_group_wait(struct spdk_fd_group *fgrp, int timeout)
{
	struct spdk_fd_group *owner;
	uint32_t totalfds = fgrp->num_fds;
	struct epoll_event events[totalfds];
	struct event_handler *ehdlr;
@@ -669,7 +678,12 @@ spdk_fd_group_wait(struct spdk_fd_group *fgrp, int timeout)
		}

		/* call the interrupt response function */
		owner = ehdlr->owner;
		if (owner->wrapper_fn != NULL) {
			owner->wrapper_fn(owner->wrapper_arg, ehdlr->fn, ehdlr->fn_arg);
		} else {
			ehdlr->fn(ehdlr->fn_arg);
		}
		g_event = NULL;

		/* It is possible that the ehdlr was removed
@@ -685,6 +699,23 @@ spdk_fd_group_wait(struct spdk_fd_group *fgrp, int timeout)
	return nfds;
}

int
spdk_fd_group_set_wrapper(struct spdk_fd_group *fgrp, spdk_fd_group_wrapper_fn fn, void *ctx)
{
	if (fgrp->wrapper_fn != NULL && fn != NULL) {
		return -EEXIST;
	}

	if (!TAILQ_EMPTY(&fgrp->children)) {
		return -EINVAL;
	}

	fgrp->wrapper_fn = fn;
	fgrp->wrapper_arg = ctx;

	return 0;
}

#else /* !__linux__ */

int
@@ -762,4 +793,10 @@ spdk_fd_group_nest(struct spdk_fd_group *parent, struct spdk_fd_group *child)
	return -ENOTSUP;
}

int
spdk_fd_group_set_wrapper(struct spdk_fd_group *fgrp, spdk_fd_group_wrapper_fn fn, void *ctx)
{
	return -ENOTSUP;
}

#endif /* __linux__ */
+1 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@
	spdk_fd_group_get_fd;
	spdk_fd_group_nest;
	spdk_fd_group_unnest;
	spdk_fd_group_set_wrapper;

	# public functions in xor.h
	spdk_xor_gen;