[Stgt-devel] [PATCH 02/20] iser counter events
Pete Wyckoff
pw
Tue Oct 16 17:18:57 CEST 2007
Like fd event handling, also handle integer counter events. This will
be used in RDMA to make progress on a connection, necessary because
RDMA API does not have a file descriptor that can be used with poll
to detect connection writability.
Signed-off-by: Pete Wyckoff <pw at osc.edu>
---
usr/tgtd.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
usr/tgtd.h | 4 +++
2 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/usr/tgtd.c b/usr/tgtd.c
index 42e21f4..6744534 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -41,9 +41,15 @@
#define MAX_FDS 4096
struct tgt_event {
- event_handler_t *handler;
+ union {
+ event_handler_t *handler;
+ counter_event_handler_t *counter_handler;
+ };
+ union {
+ int fd;
+ int *counter;
+ };
void *data;
- int fd;
struct list_head e_list;
};
@@ -52,6 +58,7 @@ unsigned long pagesize, pageshift, pagemask;
static int ep_fd;
static char program_name[] = "tgtd";
static LIST_HEAD(tgt_events_list);
+static LIST_HEAD(tgt_counter_events_list);
static struct option const long_options[] =
{
@@ -129,6 +136,22 @@ int tgt_event_add(int fd, int events, event_handler_t handler, void *data)
return err;
}
+int tgt_counter_event_add(int *counter, counter_event_handler_t handler,
+ void *data)
+{
+ struct tgt_event *tev;
+
+ tev = zalloc(sizeof(*tev));
+ if (!tev)
+ return -ENOMEM;
+
+ tev->data = data;
+ tev->counter_handler = handler;
+ tev->counter = counter;
+ list_add(&tev->e_list, &tgt_counter_events_list);
+ return 0;
+}
+
static struct tgt_event *tgt_event_lookup(int fd)
{
struct tgt_event *tev;
@@ -140,6 +163,17 @@ static struct tgt_event *tgt_event_lookup(int fd)
return NULL;
}
+static struct tgt_event *tgt_counter_event_lookup(int *counter)
+{
+ struct tgt_event *tev;
+
+ list_for_each_entry(tev, &tgt_counter_events_list, e_list) {
+ if (tev->counter == counter)
+ return tev;
+ }
+ return NULL;
+}
+
void tgt_event_del(int fd)
{
struct tgt_event *tev;
@@ -155,6 +189,20 @@ void tgt_event_del(int fd)
free(tev);
}
+void tgt_counter_event_del(int *counter)
+{
+ struct tgt_event *tev;
+
+ tev = tgt_counter_event_lookup(counter);
+ if (!tev) {
+ eprintf("Cannot find counter event %p\n", counter);
+ return;
+ }
+
+ list_del(&tev->e_list);
+ free(tev);
+}
+
int tgt_event_modify(int fd, int events)
{
struct epoll_event ev;
@@ -174,11 +222,25 @@ int tgt_event_modify(int fd, int events)
static void event_loop(void)
{
- int nevent, i, timeout = TGTD_TICK_PERIOD * 1000;
+ int nevent, i, done, timeout = TGTD_TICK_PERIOD * 1000;
struct epoll_event events[1024];
- struct tgt_event *tev;
+ struct tgt_event *tev, *tevn;
retry:
+ /*
+ * Check the counter events to see if they have any work to run.
+ */
+ do {
+ done = 1;
+ list_for_each_entry_safe(tev, tevn, &tgt_counter_events_list,
+ e_list) {
+ if (*tev->counter) {
+ done = 0;
+ tev->counter_handler(tev->counter, tev->data);
+ }
+ }
+ } while (!done);
+
nevent = epoll_wait(ep_fd, events, ARRAY_SIZE(events), timeout);
if (nevent < 0) {
if (errno != EINTR) {
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 8d5b2b6..1f8e33b 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -209,8 +209,12 @@ extern int tgt_unbind_host_to_target(int tid, int host_no);
extern int tgt_bound_target_lookup(int host_no);
typedef void (event_handler_t)(int fd, int events, void *data);
+typedef void (counter_event_handler_t)(int *counter, void *data);
extern int tgt_event_add(int fd, int events, event_handler_t handler, void *data);
+extern int tgt_counter_event_add(int *counter, counter_event_handler_t handler,
+ void *data);
extern void tgt_event_del(int fd);
+extern void tgt_counter_event_del(int *counter);
extern int tgt_event_modify(int fd, int events);
extern int target_cmd_queue(int tid, struct scsi_cmd *cmd);
extern void target_cmd_done(struct scsi_cmd *cmd);
--
1.5.3.4
More information about the stgt
mailing list