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 -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/1378399123-19493-5-git-send-email-4win...@informatik.uni-hamburg.de

