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>
Wed, 10 May 2017 18:42:59 +0000 (20:42 +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..e27aeeb
--- /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..c5489eb
--- /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 */