--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 */