[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH 4/7] libnotify: add a general notification library



XXX
---
 libnotify/Makefile |   28 ++++++++++
 libnotify/notify.c |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 libnotify/notify.h |   50 +++++++++++++++++
 3 files changed, 230 insertions(+)
 create mode 100644 libnotify/Makefile
 create mode 100644 libnotify/notify.c
 create mode 100644 libnotify/notify.h

diff --git a/libnotify/Makefile b/libnotify/Makefile
new file mode 100644
index 0000000..64d55b5
--- /dev/null
+++ b/libnotify/Makefile
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Hurd.
+#
+# The GNU Hurd is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2, or (at
+# your option) any later version.
+#
+# The GNU Hurd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.
+
+dir := libnotify
+makemode := library
+
+libname := libnotify
+SRCS = notify.c
+installhdrs = notify.h
+
+OBJS = $(SRCS:.c=.o)
+HURDLIBS = ihash
+
+include ../Makeconf
diff --git a/libnotify/notify.c b/libnotify/notify.c
new file mode 100644
index 0000000..9419e3c
--- /dev/null
+++ b/libnotify/notify.c
@@ -0,0 +1,152 @@
+/* XXX */
+
+#include <hurd/notify.h>
+#include <stdlib.h>
+#include <time.h>
+
+/* XXX */
+void
+hurd_notify_init (hurd_notify_t n, hurd_notify_func_t notify_func)
+{
+  hurd_ihash_init (&n->receivers, HURD_IHASH_NO_LOCP);
+  n->notify_func = notify_func;
+}
+
+/* XXX */
+void
+hurd_notify_destroy (hurd_notify_t n)
+{
+  hurd_ihash_destroy (&n->receivers);
+}
+
+/* XXX */
+error_t
+hurd_notify_create (hurd_notify_t *n, hurd_notify_func_t notify_func)
+{
+  *n = malloc (sizeof (struct hurd_notify));
+  if (*n == NULL)
+    return ENOMEM;
+
+  hurd_notify_init (*n, notify_func);
+
+  return 0;
+}
+
+/* XXX */
+void
+hurd_notify_free (hurd_notify_t n)
+{
+  hurd_notify_destroy (n);
+  free (n);
+}
+
+/* XXX */
+error_t
+hurd_notify_add (hurd_notify_t n, mach_port_t notify, void *data)
+{
+  return hurd_ihash_add (&n->receivers, notify, data);
+}
+
+/* XXX */
+int
+hurd_notify_remove (hurd_notify_t n, mach_port_t notify)
+{
+  return hurd_ihash_remove (&n->receivers, notify);
+}
+
+
+/* XXX */
+error_t
+hurd_notify_do_notify (hurd_notify_t n, void *common_data)
+{
+  error_t err;
+  HURD_IHASH_ITERATE_ITEMS (&n->receivers, item)
+    {
+      err = n->notify_func (item->key,
+                            MACH_PORT_NULL,
+                            item->value,
+                            common_data);
+      if (err == MACH_SEND_INVALID_DEST)
+        hurd_notify_remove (n, item->key);
+    }
+
+  return 0;
+}
+
+/* XXX */
+error_t
+hurd_notify_do_notify_wait (hurd_notify_t n,
+                            void *common_data,
+                            natural_t timeout)
+{
+  error_t err;
+  mach_port_t port_set;
+  err = mach_port_allocate (mach_task_self (),
+                            MACH_PORT_RIGHT_PORT_SET,
+                            &port_set);
+  if (err)
+    return err;
+
+  int count = 0;
+  HURD_IHASH_ITERATE_ITEMS (&n->receivers, item)
+    {
+      mach_port_t reply_port = mach_reply_port ();
+      if (reply_port == MACH_PORT_NULL)
+        return ENOMEM; /* XXX */
+
+      err = mach_port_move_member (mach_task_self (),
+                                   reply_port,
+                                   port_set);
+      if (err)
+        return err; /* XXX */
+
+      err = n->notify_func (item->key,
+                            reply_port,
+                            item->value,
+                            common_data);
+      if (err == MACH_SEND_INVALID_DEST)
+        {
+          hurd_notify_remove (n, item->key);
+          continue;
+        }
+
+      count += 1;
+    }
+
+  time_t start_time = time (NULL);
+  time_t remaining_time;
+  while (count > 0 &&
+         (remaining_time = timeout - (time (NULL) - start_time) * 1000) > 0)
+    {
+      struct Reply {
+        mach_msg_header_t Head;
+        mach_msg_type_t RetCodeType;
+        kern_return_t RetCode;
+      } reply;
+
+      /* Receive a reply message from any port in our port set with
+         timeout being set to the remaining time.  */
+      err = mach_msg (&reply.Head,
+                      MACH_RCV_MSG|MACH_MSG_OPTION_NONE|MACH_RCV_TIMEOUT,
+                      0,
+                      sizeof (struct Reply),
+                      port_set,
+                      remaining_time,
+                      MACH_PORT_NULL);
+      if (err)
+        return err; /* XXX */
+
+      /* Remove that port from the set.  */
+      err = mach_port_move_member (mach_task_self (),
+                                   reply.Head.msgh_remote_port,
+                                   MACH_PORT_NULL);
+      if (err)
+        return err; /* XXX */
+
+      mach_port_deallocate (mach_task_self (), reply.Head.msgh_remote_port);
+
+      count -= 1;
+    }
+
+  return 0;
+}
diff --git a/libnotify/notify.h b/libnotify/notify.h
new file mode 100644
index 0000000..6459640
--- /dev/null
+++ b/libnotify/notify.h
@@ -0,0 +1,50 @@
+/* XXX */
+
+#ifndef _HURD_NOTIFY_H
+#define _HURD_NOTIFY_H
+
+#include <hurd/ihash.h>
+#include <mach.h>
+
+/* XXX */
+typedef error_t (*hurd_notify_func_t) (mach_port_t port,
+                                       mach_port_t reply_port,
+                                       void *data,
+                                       void *common_data);
+
+/* XXX */
+struct hurd_notify
+{
+  struct hurd_ihash receivers;
+  hurd_notify_func_t notify_func;
+};
+
+typedef struct hurd_notify *hurd_notify_t;
+
+/* XXX */
+void hurd_notify_init (hurd_notify_t n, hurd_notify_func_t notify_func);
+
+/* XXX */
+void hurd_notify_destroy (hurd_notify_t n);
+
+/* XXX */
+error_t hurd_notify_create (hurd_notify_t *n, hurd_notify_func_t notify_func);
+
+/* XXX */
+void hurd_notify_free (hurd_notify_t n);
+
+/* XXX */
+error_t hurd_notify_add (hurd_notify_t n, mach_port_t notify, void *data);
+
+/* XXX */
+int hurd_notify_remove (hurd_notify_t n, mach_port_t notify);
+
+/* XXX */
+error_t hurd_notify_do_notify (hurd_notify_t n, void *common_data);
+
+/* XXX */
+error_t hurd_notify_do_notify_wait (hurd_notify_t n,
+                                    void *common_data,
+                                    natural_t timeout);
+
+#endif	/* _HURD_NOTIFY_H */
-- 
1.7.10.4


Reply to: