aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/afb-plugin.h10
-rw-r--r--include/afb-poll-itf.h29
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/afb-apis.c19
-rw-r--r--src/main.c1
-rw-r--r--src/utils-upoll.c142
-rw-r--r--src/utils-upoll.h29
7 files changed, 225 insertions, 9 deletions
diff --git a/include/afb-plugin.h b/include/afb-plugin.h
index 88938e3d..ba86e181 100644
--- a/include/afb-plugin.h
+++ b/include/afb-plugin.h
@@ -61,19 +61,13 @@ enum AFB_Mode {
AFB_MODE_GLOBAL
};
-/*
-typedef enum AFB_pluginE AFB_pluginE;
-typedef enum AFB_sessionE AFB_sessionE;
-typedef void (*AFB_apiCB)(struct afb_req);
-typedef void (*AFB_freeCtxCB)(void*);
-typedef struct AFB_restapi AFB_restapi;
-typedef struct AFB_plugin AFB_plugin;
-*/
+struct afb_poll;
struct AFB_interface
{
int verbosity;
enum AFB_Mode mode;
+ struct afb_poll (*poll_open)(int fd, uint32_t events, void (*process)(void *closure, int fd, uint32_t events), void *closure);
};
extern const struct AFB_plugin *pluginRegister (const struct AFB_interface *interface);
diff --git a/include/afb-poll-itf.h b/include/afb-poll-itf.h
new file mode 100644
index 00000000..4ce1fa48
--- /dev/null
+++ b/include/afb-poll-itf.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 IoT.bzh
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * 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.
+ */
+
+struct afb_poll_itf
+{
+ int (*update)(void *data, uint32_t events);
+ void (*close)(void *data);
+};
+
+struct afb_poll
+{
+ const struct afb_poll_itf *itf;
+ void *data;
+};
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7e02578e..d8bddcf0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,7 +8,9 @@ ADD_LIBRARY(src OBJECT
afb-hreq.c
afb-websock.c
websock.c
- verbose.c)
+ verbose.c
+ utils-upoll.c
+)
INCLUDE_DIRECTORIES(${include_dirs})
diff --git a/src/afb-apis.c b/src/afb-apis.c
index 7634dca1..8dfac519 100644
--- a/src/afb-apis.c
+++ b/src/afb-apis.c
@@ -41,9 +41,12 @@
#include "afb-plugin.h"
#include "afb-req-itf.h"
+#include "afb-poll-itf.h"
+
#include "session.h"
#include "afb-apis.h"
#include "verbose.h"
+#include "utils-upoll.h"
struct api_desc {
struct AFB_plugin *plugin; /* descriptor */
@@ -59,6 +62,12 @@ static int apis_count = 0;
static const char plugin_register_function[] = "pluginRegister";
+static const struct afb_poll_itf upoll_itf = {
+ .update = (void*)upoll_update,
+ .close = (void*)upoll_close
+};
+
+
int afb_apis_count()
{
return apis_count;
@@ -76,6 +85,15 @@ void afb_apis_free_context(int apiidx, void *context)
free(context);
}
+static struct afb_poll itf_poll_open(int fd, uint32_t events, void (*process)(void *closure, int fd, uint32_t events), void *closure)
+{
+ struct afb_poll result;
+ result.data = upoll_open(fd, events, process, closure);
+ result.itf = result.data ? &upoll_itf : NULL;
+ return result;
+}
+
+
int afb_apis_add_plugin(const char *path)
{
struct api_desc *apis;
@@ -117,6 +135,7 @@ int afb_apis_add_plugin(const char *path)
}
interface->verbosity = 0;
interface->mode = AFB_MODE_LOCAL;
+ interface->poll_open = itf_poll_open;
/* init the plugin */
plugin = pluginRegisterFct(interface);
diff --git a/src/main.c b/src/main.c
index 37183e72..15f84b18 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <stdint.h>
#include "afb-plugin.h"
diff --git a/src/utils-upoll.c b/src/utils-upoll.c
new file mode 100644
index 00000000..af4a6161
--- /dev/null
+++ b/src/utils-upoll.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2016 IoT.bzh
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * 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 <sys/epoll.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "utils-upoll.h"
+
+
+struct upoll
+{
+ int fd;
+ void (*process)(void *closure, int fd, uint32_t events);
+ void *closure;
+ struct upoll *next;
+};
+
+static int pollfd = 0;
+static struct upoll *head = NULL;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int upoll_is_valid(struct upoll *upoll)
+{
+ struct upoll *it = head;
+ while (it != NULL) {
+ if (it == upoll)
+ return 1;
+ it = it->next;
+ }
+ return 0;
+}
+
+struct upoll *upoll_open(int fd, uint32_t events, void (*process)(void *closure, int fd, uint32_t events), void *closure)
+{
+ struct epoll_event e;
+ struct upoll *result;
+ int rc;
+
+ /* opens the epoll stream */
+ if (pollfd == 0) {
+ pollfd = epoll_create1(EPOLL_CLOEXEC);
+ if (pollfd == 0) {
+ pollfd = dup(0);
+ close(0);
+ }
+ if (pollfd < 0) {
+ pollfd = 0;
+ return NULL;
+ }
+ }
+
+ /* allocates */
+ result = malloc(sizeof *result);
+ if (result == NULL)
+ return NULL;
+
+ /* init */
+ result->fd = fd;
+ result->process = process;
+ result->closure = closure;
+ pthread_mutex_lock(&mutex);
+ result->next = head;
+ head = result;
+ pthread_mutex_unlock(&mutex);
+
+ /* records */
+ e.events = events;
+ e.data.ptr = result;
+ rc = epoll_ctl(pollfd, EPOLL_CTL_ADD, fd, &e);
+ if (rc == 0)
+ return result;
+
+ /* revert on error */
+ rc = errno;
+ upoll_close(result);
+ errno = rc;
+ return NULL;
+}
+
+int upoll_update(struct upoll *upoll, uint32_t events)
+{
+ struct epoll_event e;
+
+ assert(pollfd != 0);
+ assert(upoll_is_valid(upoll));
+
+ e.events = events;
+ e.data.ptr = upoll;
+ return epoll_ctl(pollfd, EPOLL_CTL_MOD, upoll->fd, &e);
+}
+
+void upoll_close(struct upoll *upoll)
+{
+ struct upoll **it;
+
+ assert(pollfd != 0);
+ assert(upoll_is_valid(upoll));
+
+ epoll_ctl(pollfd, EPOLL_CTL_DEL, upoll->fd, NULL);
+ pthread_mutex_lock(&mutex);
+ it = &head;
+ while (*it != upoll)
+ it = &(*it)->next;
+ *it = upoll->next;
+ pthread_mutex_unlock(&mutex);
+ free(upoll);
+}
+
+void upoll_wait(int timeout)
+{
+ int rc;
+ struct epoll_event e;
+ struct upoll *upoll;
+
+ if (pollfd == 0)
+ return;
+
+ rc = epoll_wait(pollfd, &e, 1, timeout);
+ if (rc == 1) {
+ upoll = e.data.ptr;
+ upoll->process(upoll->closure, upoll->fd, e.events);
+ }
+}
+
diff --git a/src/utils-upoll.h b/src/utils-upoll.h
new file mode 100644
index 00000000..24aaf41a
--- /dev/null
+++ b/src/utils-upoll.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 IoT.bzh
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * 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.
+ */
+
+struct upoll;
+
+extern int upoll_is_valid(struct upoll *upoll);
+
+extern struct upoll *upoll_open(int fd, uint32_t events, void (*process)(void *closure, int fd, uint32_t events), void *closure);
+
+extern int upoll_update(struct upoll *upoll, uint32_t events);
+
+extern void upoll_close(struct upoll *upoll);
+
+extern void upoll_wait(int timeout);
+