Add queue with fd notification
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Mon, 8 May 2017 20:54:07 +0000 (22:54 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 9 May 2017 11:40:23 +0000 (13:40 +0200)
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
src/util/notify_queue.c [new file with mode: 0644]
src/util/notify_queue.h [new file with mode: 0644]

diff --git a/src/util/notify_queue.c b/src/util/notify_queue.c
new file mode 100644 (file)
index 0000000..125d766
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * faultd
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "notify_queue.h"
+
+#include <sys/eventfd.h>
+#include <errno.h>
+
+int init_notify_queue_head(struct nqueue_head *head)
+{
+        int ret;
+
+        ret = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
+        if (ret < 0)
+                return errno;
+
+        INIT_QUEUE_HEAD(&head->qhead);
+        head->fd = ret;
+
+        return 0;
+}
+
+void cleanup_notify_queue_head(struct nqueue_head *head)
+{
+        close(head->fd);
+}
diff --git a/src/util/notify_queue.h b/src/util/notify_queue.h
new file mode 100644 (file)
index 0000000..6bdfb8d
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * faultd
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FAULTD_NOTIFY_QUEUE_H
+#define FAULTD_NOTIFY_QUEUE_H
+
+#include <unistd.h>
+#include <stdint.h>
+
+#include "queue.h"
+
+/*
+ * Simple queue with fd notification for use in main loop
+ */
+
+struct nqueue_head {
+        int fd;
+        struct queue_head qhead;
+};
+
+#define nqueue_node queue_head
+
+int init_notify_queue_head(struct nqueue_head *head);
+
+void cleanup_notify_queue_head(struct nqueue_head *head);
+
+static inline int nqueue_get_notify_fd(struct nqueue_head *head)
+{
+        return head->fd;
+}
+
+#define NQUEUE_NODE_INIT(node) QUEUE_INIT(node)
+
+#define INIT_NQUEUE_NODE(node) INIT_QUEUE_HEAD(node)
+
+static inline int nqueue_append(struct nqueue_head *head,
+                                struct nqueue_node *new)
+{
+        ssize_t ret;
+        uint64_t buf = 1;
+
+        ret = write(head->fd, &buf, sizeof(buf));
+        if (ret == sizeof(buf)) {
+                queue_append(&head->qhead, new);
+                ret = 0;
+        }
+
+        return ret;
+}
+
+#define nqueue_pop(head, type, member) ({                               \
+        ssize_t ret__;                                                  \
+        uint64_t buf__;                                                 \
+        ret__ = read((head)->fd, &buf__, sizeof(buf__));                \
+        ret__ > 0 && buf__ > 0 ?                                        \
+                queue_pop(&(head)->qhead, type, member) : NULL;         \
+})
+
+#define nqueue_empty(head) queue_empty(&(head)->qhead)
+
+#define nqueue_for_each(pos, head) \
+        queue_for_each(pos, &(head)->qhead)
+
+#define nqueue_for_each_safe(pos, n, head)       \
+        queue_for_each_safe(pos, n, &(head)->qhead)
+
+#define nqueue_for_each_entry(pos, head, member) \
+        queue_for_each_entry(pos, &(head)->qhead, member)
+
+#define nqueue_for_each_entry_safe(pos, n, head, member) \
+        queue_for_each_entry_safe(pos, n, &(head)->qhead, member)
+
+#endif /* FAULTD_NOTIFY_QUEUE_H */