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 <[EMAIL PROTECTED]>
---
 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

_______________________________________________
Stgt-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/stgt-devel

Reply via email to