SET(VINE_VERSION_PATCH "0")
SET(VINE_VERSION ${VINE_VERSION_MAJOR}.${VINE_VERSION_MINOR}.${VINE_VERSION_PATCH})
+OPTION(USE_EVENT_LOOP_EPOLL "Use epoll event loop" ON)
OPTION(USE_LIBWEBSOCKETS "Use libwebsockets for data path" ON)
OPTION(USE_LIBWEBSOCKETS_STATIC "Use libwebsockets static library" ON)
OPTION(USE_LIBWEBSOCKETS_STATIC_PREBUILT "Use prebuilt static library(.a)" ON)
ADD_SUBDIRECTORY(plugins/libwebsockets)
ENDIF(USE_LIBWEBSOCKETS)
+iF(USE_EVENT_LOOP_EPOLL)
+ ADD_DEFINITIONS("-DVINE_EVENT_LOOP_EPOLL")
+ENDIF(USE_EVENT_LOOP_EPOLL)
+
ADD_SUBDIRECTORY(plugins/dns-sd)
ADD_SUBDIRECTORY(include)
vine_data_path_opened_cb opened_cb, void *opened_cb_data,
vine_data_path_accepted_cb accepted_cb, void *accepted_cb_data,
vine_data_path_h *opened_datapath,
- vine_event_queue_h event_fd);
+ vine_event_queue_h event_queue);
int vine_data_path_connect(vine_address_family_e addr_family,
const char *ip, int port, const char *iface_name,
vine_security_h security, const char *host_name, const char *token,
vine_data_path_connected_cb callback, void *user_data,
vine_data_path_h *connected_datapath,
- vine_event_queue_h event_fd);
+ vine_event_queue_h event_queue);
const char *vine_data_path_get_ip(vine_data_path_h datapath);
vine_address_family_e vine_data_path_get_addr_family(vine_data_path_h datapath);
int vine_disc_publish(vine_disc_h disc,
vine_service_h service, const char *iface_name,
vine_disc_published_cb cb, void *user_data,
- vine_event_queue_h event_fd);
+ vine_event_queue_h event_queue);
int vine_disc_stop_publish(vine_disc_h disc);
int vine_disc_subscribe(vine_disc_h disc,
const char *service_type, const char *iface_name,
vine_disc_discovered_cb cb, void *user_data,
- vine_event_queue_h event_fd);
+ vine_event_queue_h event_queue);
int vine_disc_stop_subscribe(vine_disc_h disc);
int vine_disc_resolve_ip(vine_disc_h disc,
vine_service_h service,
vine_disc_ip_resolved_cb cb, void *user_data,
- vine_event_queue_h event_fd);
+ vine_event_queue_h event_queue);
int vine_disc_cancel_resolve_ip(vine_disc_h disc, vine_service_h service);
bool vine_disc_is_plugin_loaded(vine_discovery_method_e disc_method);
virtual int set_peer_left_cb(vine_dp_peer_left_cb callback, void *user_data) = 0;
virtual int unset_peer_left_cb() = 0;
- void *get_eventfd() { return mEventFd; }
+ void *get_eventfd() { return mEventQueue; }
int set_security(void *security);
int set_iface_name(const std::string &iface_name);
void invoke_received_cb(size_t received_len);
protected:
- void *mEventFd;
+ void *mEventQueue;
void *mSecurity;
std::string mIfaceName;
int mOpenState;
class DPServer : DataPath
{
public:
- DPServer(void *event_fd);
+ DPServer(void *event_queue);
virtual ~DPServer();
virtual int open(vine_dp_opened_cb callback, void *user_data);
class DPClient : DataPath
{
public:
- DPClient(void *event_fd);
- DPClient(void *event_fd, void *datapath);
+ DPClient(void *event_queue);
+ DPClient(void *event_queue, void *datapath);
virtual ~DPClient();
virtual int open(vine_dp_opened_cb callback, void *user_data);
class DPPubSub : DataPath
{
public:
- DPPubSub(void *event_fd);
+ DPPubSub(void *event_queue);
virtual ~DPPubSub();
virtual int open(vine_dp_opened_cb callback, void *user_data);
--- /dev/null
+/*\r
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+*/\r
+\r
+#pragma once\r
+\r
int vine_event_loop_start();
void vine_event_loop_stop();
-int vine_event_queue_create(vine_event_queue_h *event_fd);
-void vine_event_queue_destroy(vine_event_queue_h event_fd);
+int vine_event_queue_create(vine_event_queue_h *event_queue);
+void vine_event_queue_destroy(vine_event_queue_h event_queue);
-void vine_event_loop_get_eventfd(vine_event_queue_h event_fd, int *eventfd);
-int vine_event_loop_process(vine_event_queue_h event_fd);
+void vine_event_loop_get_eventfd(vine_event_queue_h event_queue, int *eventfd);
+int vine_event_loop_process(vine_event_queue_h event_queue);
int vine_event_loop_add_io_handler(int fd, int events,
vine_poll_handler handler, void *user_data);
vine_poll_handler handler, void *user_data);
int vine_event_loop_del_io_handler(int fd);
-int vine_event_loop_add_event(vine_event_queue_h event_fd, void *event_data,
+int vine_event_loop_add_event(vine_event_queue_h event_queue, void *event_data,
vine_event_handler handler, vine_event_free_handler free_func,
void *user_data);
+
+typedef struct {
+ int (*init)();
+ void (*deinit)();
+ int (*start)();
+ void (*stop)();
+ int (*event_queue_create)(vine_event_queue_h *event_queue);
+ void (*event_queue_destroy)(vine_event_queue_h event_queue);
+ void (*get_eventfd)(vine_event_queue_h event_queue, int *eventfd);
+ int (*process)(vine_event_queue_h event_queue);
+ int (*add_io_handler)(int fd, int events, vine_poll_handler handler, void *user_data);
+ int (*mod_io_handler)(int fd, int events, vine_poll_handler handler, void *user_data);
+ int (*del_io_handler)(int fd);
+ int (*add_event)(vine_event_queue_h event_queue, void *event_data,
+ vine_event_handler handler, vine_event_free_handler free_func,
+ void *user_data);
+} vine_event_loop_fn;
+
#define MAX_VINE_EPOLL_EVENTS 512
#endif /* __VINE_EVENT_LOOP_H__ */
void *terminated_cb_data;
vine_dp_plugin_h plugin_handle;
- vine_event_queue_h event_fd;
+ vine_event_queue_h event_queue;
VineDataPathState *state;
established_notifier established;
static void (*__init_plugin)(vine_dp_plugin_fn *fn);
static vine_data_path_s *_vine_data_path_create(vine_address_family_e addr_family,
const char *addr, int port, vine_security_h security,
- void *plugin_data, vine_event_queue_h event_fd);
+ void *plugin_data, vine_event_queue_h event_queue);
static vine_error_e __convert_data_path_error_to_vine_error(vine_data_path_error error)
{
vine_data_path_s *listen_dp = (vine_data_path_s *)dp->listen_dp;
VINE_LOGD("listen_dp[%p]", listen_dp);
if (listen_dp)
- vine_event_loop_add_event(listen_dp->event_fd, accepted_event,
+ vine_event_loop_add_event(listen_dp->event_queue, accepted_event,
__invoke_accepted_user_cb, __free_accepted_event, listen_dp);
}
opened_event->result = result;
opened_event->port = port;
- vine_event_loop_add_event(dp->event_fd, opened_event,
+ vine_event_loop_add_event(dp->event_queue, opened_event,
__invoke_opened_user_cb, free, dp);
}
VINE_LOGE("listen_dp[%p], security[%p]", listen_dp, listen_dp->security);
vine_data_path_s *connected_dp = _vine_data_path_create(__convert_addr_family(addr_family),
- addr, port, listen_dp->security, plugin_data, listen_dp->event_fd);
+ addr, port, listen_dp->security, plugin_data, listen_dp->event_queue);
RET_IF(connected_dp == NULL, "Out of memory");
VINE_LOGD("Accepted dp[%p] addr[%s] port[%d] listen_dp[%p]", connected_dp, addr, port, user_data);
connected_event->result = result;
vine_data_path_s *dp = (vine_data_path_s *)datapath;
- vine_event_loop_add_event(dp->event_fd, connected_event,
+ vine_event_loop_add_event(dp->event_queue, connected_event,
__invoke_connected_user_cb, free, datapath);
}
vine_data_path_s *dp = (vine_data_path_s *)datapath;
if (dp)
- vine_event_loop_add_event(dp->event_fd, received_event,
+ vine_event_loop_add_event(dp->event_queue, received_event,
__invoke_received_user_cb, free, datapath);
}
{
vine_data_path_s *dp = (vine_data_path_s *)user_data;
if (dp)
- vine_event_loop_add_event(dp->event_fd, NULL,
+ vine_event_loop_add_event(dp->event_queue, NULL,
__invoke_terminated_user_cb, NULL, user_data);
}
static vine_data_path_s *_vine_data_path_create(vine_address_family_e addr_family,
const char *addr, int port, vine_security_h security,
- void *plugin_data, vine_event_queue_h event_fd)
+ void *plugin_data, vine_event_queue_h event_queue)
{
RET_VAL_IF(addr == NULL, NULL, "addr is NULL");
dp->port = port;
dp->recv_cb = NULL;
dp->recv_cb_data = NULL;
- dp->event_fd = event_fd;
+ dp->event_queue = event_queue;
if (security != NULL) {
ret = _vine_security_clone(&(dp->security), security);
if (ret != VINE_ERROR_NONE) {
vine_data_path_opened_cb opened_cb, void *opened_cb_data,
vine_data_path_accepted_cb accepted_cb, void *accepted_cb_data,
vine_data_path_h *opened_datapath,
- vine_event_queue_h event_fd)
+ vine_event_queue_h event_queue)
{
vine_dp_addr_family_e dp_addr_family;
int ret = __convert_address_family(addr_family, &dp_addr_family);
}
vine_data_path_s *dp =
- _vine_data_path_create(addr_family, "", port, security, NULL, event_fd);
+ _vine_data_path_create(addr_family, "", port, security, NULL, event_queue);
RET_VAL_IF(dp == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
vine_dp_ssl ssl = {false, VINE_DP_TLS_VERSION_DEFAULT, 0, NULL, NULL, NULL};
const char *ip, int port, const char *iface_name,
vine_security_h security, const char *host_name, const char *token,
vine_data_path_connected_cb callback, void *user_data,
- vine_data_path_h *connected_datapath, vine_event_queue_h event_fd)
+ vine_data_path_h *connected_datapath, vine_event_queue_h event_queue)
{
vine_data_path_s *dp =
- _vine_data_path_create(addr_family, ip, port, security, NULL, event_fd);
+ _vine_data_path_create(addr_family, ip, port, security, NULL, event_queue);
RET_VAL_IF(dp == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
RET_VAL_IF(connected_datapath == NULL,
VINE_ERROR_INVALID_PARAMETER, "connected_datapath is NULL");
vine_service_h service; // Used only for vine_disc_resolve_ip
void *plugin_handle; // Handle to be used in each plugin
- vine_event_queue_h event_fd;
+ vine_event_queue_h event_queue;
} vine_disc_s;
typedef struct {
vine_disc_s *disc_handle = (vine_disc_s *)user_data;
if (disc_handle)
- vine_event_loop_add_event(disc_handle->event_fd, pub_event,
+ vine_event_loop_add_event(disc_handle->event_queue, pub_event,
__invoke_published_user_cb, __free_pub_event, user_data);
}
vine_disc_s *disc_handle = (vine_disc_s *)user_data;
if (disc_handle)
- vine_event_loop_add_event(disc_handle->event_fd, discovered_event,
+ vine_event_loop_add_event(disc_handle->event_queue, discovered_event,
__invoke_discovered_user_cb, __free_discovered_event,
user_data);
}
vine_disc_s *disc_handle = (vine_disc_s *)user_data;
if (disc_handle)
- vine_event_loop_add_event(disc_handle->event_fd, resolved_event,
+ vine_event_loop_add_event(disc_handle->event_queue, resolved_event,
__invoke_ip_resolved_user_cb, __free_ip_resolved_event,
user_data);
}
int vine_disc_publish(vine_disc_h disc,
vine_service_h service, const char *iface_name,
vine_disc_published_cb cb, void *user_data,
- vine_event_queue_h event_fd)
+ vine_event_queue_h event_queue)
{
RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
- VINE_LOGD("Publishevent_fd[%p]", event_fd);
+ VINE_LOGD("Publishevent_queue[%p]", event_queue);
VINE_LOGD("service[%p] disc[%p]", service, disc);
__vine_disc_set_published_cb(disc, cb, user_data);
vine_disc_s *disc_handle = (vine_disc_s *)disc;
- disc_handle->event_fd = event_fd;
+ disc_handle->event_queue = event_queue;
int ret = __vine_disc_plugin_publish(disc, service, iface_name);
if (ret != VINE_ERROR_NONE) {
int vine_disc_subscribe(vine_disc_h disc,
const char *service_type, const char *iface_name,
vine_disc_discovered_cb cb, void *user_data,
- vine_event_queue_h event_fd)
+ vine_event_queue_h event_queue)
{
RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
- VINE_LOGD("Subscribe event_fd[%p]", event_fd);
+ VINE_LOGD("Subscribe event_queue[%p]", event_queue);
VINE_LOGD("service_type[%s] disc[%p]", service_type, disc);
__vine_disc_set_discovered_cb(disc, cb, user_data);
vine_disc_s *disc_handle = (vine_disc_s *)disc;
- disc_handle->event_fd = event_fd;
+ disc_handle->event_queue = event_queue;
int ret = __vine_disc_plugin_subscribe(disc, service_type, iface_name);
if (ret != VINE_ERROR_NONE) {
int vine_disc_resolve_ip(vine_disc_h disc,
vine_service_h service,
vine_disc_ip_resolved_cb cb, void *user_data,
- vine_event_queue_h event_fd)
+ vine_event_queue_h event_queue)
{
RET_VAL_IF(disc == NULL, VINE_ERROR_INVALID_PARAMETER, "disc is NULL");
RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL");
- VINE_LOGD("Resolve IP for a service[%p] event_fd[%p]", service, event_fd);
+ VINE_LOGD("Resolve IP for a service[%p] event_queue[%p]", service, event_queue);
__vine_disc_set_ip_resolved_cb(disc, cb, user_data);
vine_disc_s *disc_handle = (vine_disc_s *)disc;
- disc_handle->event_fd = event_fd;
+ disc_handle->event_queue = event_queue;
disc_handle->service = service;
int ret = __vine_disc_plugin_resolve_ip(disc, service);
}
vine_disc_s *disc_handle = (vine_disc_s *)disc;
- disc_handle->event_fd = NULL;
+ disc_handle->event_queue = NULL;
disc_handle->service = NULL;
return VINE_ERROR_NONE;
if (!datapath || !user_data)
return;
- void *event_fd = static_cast<DataPath *>(user_data)->get_eventfd();
+ void *event_queue = static_cast<DataPath *>(user_data)->get_eventfd();
// datapath is created newly. DP class should be needed for it.
- // event_fd is the same as corresponding DPServer.
- DPClient *connected_client_dp = new DPClient(event_fd, datapath);
+ // event_queue is the same as corresponding DPServer.
+ DPClient *connected_client_dp = new DPClient(event_queue, datapath);
vine_data_path_set_received_cb(datapath,
_received_cb, static_cast<void *>(connected_client_dp));
vine_data_path_set_terminated_cb(datapath,
mTerminatedCb(static_cast<void *>(this), mTerminatedCbData);
}
-DPServer::DPServer(void *event_fd)
+DPServer::DPServer(void *event_queue)
{
VINE_LOGD("DPServer[%p] is created.", this);
- mEventFd = event_fd;
+ mEventQueue = event_queue;
mSecurity = NULL;
mAddrFamily = VINE_ADDRESS_FAMILY_DEFAULT;
mIfaceName = "";
mMaxConnNum, mSecurity, NULL,
_opened_cb, static_cast<void *>(this),
_accepted_cb, static_cast<void *>(this),
- &mDataPath, mEventFd);
+ &mDataPath, mEventQueue);
if (ret != VINE_ERROR_NONE)
mOpenState = VINE_DP_OPEN_STATE_NONE;
return vine_data_path_read(mDataPath, buf, buf_len, read_len);
}
-DPClient::DPClient(void *event_fd)
+DPClient::DPClient(void *event_queue)
{
VINE_LOGD("DPClient[%p] is created.", this);
- mEventFd = event_fd;
+ mEventQueue = event_queue;
mSecurity = NULL;
mAddrFamily = VINE_ADDRESS_FAMILY_DEFAULT;
mIfaceName = "";
isCreatedByServerDp = false;
}
-DPClient::DPClient(void *event_fd, void *datapath)
+DPClient::DPClient(void *event_queue, void *datapath)
{
VINE_LOGD("DPClient[%p] is created with datapath[%p]", this, datapath);
- mEventFd = event_fd;
+ mEventQueue = event_queue;
mSecurity = NULL;
mOpenState = VINE_DP_OPEN_STATE_NONE;
mDataPath = datapath;
int ret = vine_data_path_connect(mAddrFamily, mPeerIp.c_str(), mPeerPort,
mIfaceName.size() > 0 ? mIfaceName.c_str() : NULL,
mSecurity, NULL, NULL,
- _connected_cb, static_cast<void *>(this), &mDataPath, mEventFd);
+ _connected_cb, static_cast<void *>(this), &mDataPath, mEventQueue);
if (ret != VINE_ERROR_NONE)
mOpenState = VINE_DP_OPEN_STATE_NONE;
return ret;
return vine_data_path_read(mDataPath, buf, buf_len, read_len);
}
-DPPubSub::DPPubSub(void *event_fd)
+DPPubSub::DPPubSub(void *event_queue)
{
VINE_LOGD("DPPubSub[%p] is created.", this);
- mEventFd = event_fd;
+ mEventQueue = event_queue;
mSecurity = NULL;
mIfaceName = "";
mOpenState = VINE_DP_OPEN_STATE_NONE;
int ret = vine_data_path_connect(mAddrFamily, ip, port, iface_name,
mSecurity, service_name, mId.c_str(),
_pubsub_connected_cb, (void *)conn_data,
- &datapath, mEventFd);
+ &datapath, mEventQueue);
return ret;
}
ret = vine_disc_publish(mSdPub,
service, NULL,
_service_published_cb, static_cast<void *>(this),
- mEventFd);
+ mEventQueue);
if (ret != VINE_ERROR_NONE) {
vine_disc_destroy(mSdPub);
mSdPub = NULL;
ret = vine_disc_subscribe(mSdSub,
mTopic.c_str(), NULL,
_service_discovered_cb, static_cast<void *>(this),
- mEventFd);
+ mEventQueue);
if (ret != VINE_ERROR_NONE) {
vine_disc_destroy(mSdSub);
mSdSub = NULL;
mMaxConnNum, mSecurity, mId.c_str(),
_pubsub_opened_cb, static_cast<void *>(this),
_pubsub_accepted_cb, static_cast<void *>(this),
- &mServerDataPath, mEventFd);
+ &mServerDataPath, mEventQueue);
if (ret != VINE_ERROR_NONE) {
mOpenedCb = NULL;
mOpenedCbData = NULL;
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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/eventfd.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "vine.h"
+#include "vine-event-loop.h"
+#include "vine-queue.h"
+#include "vine-log.h"
+#include "vine-utils.h"
+
+static pthread_t __vine_event_loop_epoll_tid = 0;
+
+static bool __cleanup = false;
+static int __vine_epoll_fd = 0;
+//static struct epoll_event __vine_epoll_events[MAX_VINE_EPOLL_EVENTS];
+//static int __vine_epoll_events_idx = 0;
+
+typedef struct {
+ int fd;
+ vine_poll_handler handler;
+ void *user_data;
+} vine_epoll_io_event_handler;
+
+typedef struct {
+ void *event_data;
+ vine_event_handler handler;
+ vine_event_free_handler free_func;
+ void *user_data;
+} vine_epoll_event;
+
+typedef struct {
+ int fd;
+ VineQueue<vine_epoll_event *> event_queue;
+} vine_epoll_event_queue_s;
+
+#ifdef FD_SETSIZE
+#define MAX_IO_EVENT_HANDLERS FD_SETSIZE
+#else
+#define MAX_IO_EVENT_HANDLERS MAX_VINE_EPOLL_EVENTS
+#endif
+
+static vine_epoll_io_event_handler *io_event_handlers[MAX_IO_EVENT_HANDLERS] = {0, };
+
+static void *__vine_event_loop_epoll_run(void *arg)
+{
+ VINE_LOGD("Run Vine event loop");
+
+ struct epoll_event events[MAX_VINE_EPOLL_EVENTS];
+ int timeout = -1;
+
+ do {
+ int n = epoll_wait(__vine_epoll_fd, events, MAX_VINE_EPOLL_EVENTS, timeout);
+ if (n == -1) {
+ VINE_LOGE("Invalid return value");
+ break;
+ }
+
+ for (int i = 0; i < n; ++i) {
+ vine_epoll_io_event_handler *h = (vine_epoll_io_event_handler *)events[i].data.ptr;
+ if (h && h->handler)
+ h->handler(h->fd, events[i].events, h->user_data);
+ }
+ } while (!__cleanup);
+
+ // TODO:
+ // Even although __cleanup is set as false,
+ // this loop cannot be broken if waiting epoll_wait()
+ // --> socketpair()? timeout?
+
+ return NULL;
+}
+
+int vine_event_loop_epoll_init()
+{
+ __vine_epoll_fd = epoll_create1(0);
+ if (__vine_epoll_fd == -1) {
+ VINE_LOGE("Fail to create epoll fd. error %d", errno);
+ return VINE_ERROR_OPERATION_FAILED;
+ }
+
+ __cleanup = false;
+
+ return VINE_ERROR_NONE;
+}
+
+void vine_event_loop_epoll_deinit()
+{
+ close(__vine_epoll_fd);
+}
+
+int vine_event_loop_epoll_start()
+{
+ VINE_LOGD("vine_event_loop_start");
+ if (__vine_event_loop_epoll_tid) {
+ VINE_LOGD("Vine event loop was already executed");
+ return VINE_ERROR_NONE;
+ }
+
+ if (pthread_create(&__vine_event_loop_epoll_tid, NULL,
+ __vine_event_loop_epoll_run, NULL) != 0) {
+ VINE_LOGE("Fail to create event thread");
+ return VINE_ERROR_OPERATION_FAILED;
+ }
+
+ // pthread_detach(__vine_event_loop_tid);
+
+ return VINE_ERROR_NONE;
+}
+
+static void _vine_event_loop_epoll_wake_up()
+{
+ uint64_t v = 1;
+ int fd = eventfd(0, 0);
+
+ VINE_LOGD("fd[%d] to wake the eventloop up", fd);
+ vine_event_loop_add_io_handler(fd, VINE_POLLOUT, NULL, NULL);
+ if (write(fd, &v, sizeof(v)) == -1)
+ VINE_LOGE("Write error(%d)", errno);
+}
+
+void vine_event_loop_epoll_stop()
+{
+ VINE_LOGD("vine_event_loop_stop");
+ __cleanup = true;
+ _vine_event_loop_epoll_wake_up();
+ pthread_join(__vine_event_loop_epoll_tid, NULL);
+ __vine_event_loop_epoll_tid = 0;
+}
+
+int vine_event_queue_epoll_create(vine_event_queue_h *event_queue)
+{
+ vine_epoll_event_queue_s *event_queue_handle = new vine_epoll_event_queue_s;
+ VINE_LOGD("New Event Loop handle[%p]", event_queue_handle);
+
+ *event_queue = event_queue_handle;
+ event_queue_handle->fd = eventfd(0, 0);
+ if (event_queue_handle->fd == -1) {
+ VINE_LOGE("Fail to create eventfd. error %d", errno);
+ delete event_queue_handle;
+ return VINE_ERROR_OPERATION_FAILED;
+ }
+ VINE_LOGD("Event FD: %d", event_queue_handle->fd);
+
+ return VINE_ERROR_NONE;
+}
+
+void vine_event_queue_epoll_destroy(vine_event_queue_h event_queue)
+{
+ vine_epoll_event_queue_s *event_queue_handle = (vine_epoll_event_queue_s *)event_queue;
+
+ vine_epoll_event *event = NULL;
+ while(!event_queue_handle->event_queue.empty()) {
+ event = event_queue_handle->event_queue.front();
+ if (event && event->free_func)
+ event->free_func(event->event_data);
+ event_queue_handle->event_queue.pop();
+ free(event);
+ }
+
+ if (event_queue_handle->fd >= 0)
+ close(event_queue_handle->fd);
+ delete event_queue_handle;
+}
+
+void vine_event_loop_epoll_get_eventfd(vine_event_queue_h event_queue, int *eventfd)
+{
+ vine_epoll_event_queue_s *event_queue_handle = (vine_epoll_event_queue_s *)event_queue;
+ *eventfd = event_queue_handle->fd;
+}
+
+static void _add_io_event_handler(int fd, vine_epoll_io_event_handler *h)
+{
+ if (io_event_handlers[fd])
+ free(io_event_handlers[fd]);
+ io_event_handlers[fd] = h;
+}
+
+static void _del_io_event_handler(int fd)
+{
+ if (io_event_handlers[fd]) {
+ free(io_event_handlers[fd]);
+ io_event_handlers[fd] = NULL;
+ }
+}
+
+static vine_epoll_io_event_handler *_find_io_event_handler(int fd)
+{
+ return io_event_handlers[fd];
+}
+
+int vine_event_loop_epoll_add_io_handler(
+ int fd, int events, vine_poll_handler handler, void *user_data)
+{
+ RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
+ "fd should be equal to or greater than zero");
+
+ vine_epoll_io_event_handler *h =
+ (vine_epoll_io_event_handler *)calloc(1, sizeof(vine_epoll_io_event_handler));
+ RET_VAL_IF(h == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
+ h->fd = fd;
+ h->handler = handler;
+ h->user_data = user_data;
+ _add_io_event_handler(fd, h);
+
+ struct epoll_event event;
+ event.events = events;
+ event.data.ptr = (void *)h;
+
+ epoll_ctl(__vine_epoll_fd, EPOLL_CTL_ADD, fd, &event);
+ VINE_LOGD("Add an epoll event. fd: %d", fd);
+
+ return VINE_ERROR_NONE;
+}
+
+int vine_event_loop_epoll_mod_io_handler(
+ int fd, int events, vine_poll_handler handler, void *user_data)
+{
+ RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
+ "fd should be equal to or greater than zero");
+
+ struct epoll_event event;
+ event.events = events;
+ event.data.ptr = _find_io_event_handler(fd);
+
+ epoll_ctl(__vine_epoll_fd, EPOLL_CTL_MOD, fd, &event);
+ VINE_LOGD("Modify an epoll event. fd: %d event: %d", fd, events);
+
+ return VINE_ERROR_NONE;
+}
+
+int vine_event_loop_epoll_del_io_handler(int fd)
+{
+ RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
+ "fd should be equal to or greater than zero");
+
+ epoll_ctl(__vine_epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+ _del_io_event_handler(fd);
+ VINE_LOGD("Del an epoll event. fd: %d", fd);
+
+ return VINE_ERROR_NONE;
+}
+
+// Register an event handler which is called in vine_event_loop_process()
+// And then, an appropriate user callback will be called by the handler.
+int vine_event_loop_epoll_add_event(vine_event_queue_h event_queue, void *event_data,
+ vine_event_handler handler, vine_event_free_handler free_func,
+ void *user_data)
+{
+ VINE_LOGD("event_data[%p] event_queue[%p]", event_data, event_queue);
+ vine_epoll_event_queue_s *event_queue_handle = (vine_epoll_event_queue_s *)event_queue;
+ RET_VAL_IF(event_queue == NULL, VINE_ERROR_INVALID_OPERATION, "event_queue is NULL");
+
+ vine_epoll_event *event = (vine_epoll_event *)calloc(1, sizeof(vine_epoll_event));
+ RET_VAL_IF(event == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
+
+ event->event_data = event_data;
+ event->handler = handler;
+ event->free_func = free_func;
+ event->user_data = user_data;
+ VINE_LOGD("Vine event[%p]", event);
+
+ event_queue_handle->event_queue.push(event);
+
+ uint64_t u = 1;
+ if (write(event_queue_handle->fd, &u, sizeof(uint64_t)) == -1) {
+ VINE_LOGE("Write error(%d)", errno);
+ return VINE_ERROR_OPERATION_FAILED;
+ }
+
+ return VINE_ERROR_NONE;
+}
+
+int vine_event_loop_epoll_process(vine_event_queue_h event_queue)
+{
+ VINE_LOGD("Process a vine event. event_queue[%p]", event_queue);
+ vine_epoll_event_queue_s *event_queue_handle = (vine_epoll_event_queue_s *)event_queue;
+ RET_VAL_IF(event_queue == NULL, VINE_ERROR_INVALID_OPERATION, "event_queue is NULL");
+
+ uint64_t u;
+ if (read(event_queue_handle->fd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) {
+ VINE_LOGE("Read error(%d)", errno);
+ return VINE_ERROR_OPERATION_FAILED;
+ }
+
+ VINE_LOGD("eventfd counter: %lld", u);
+
+ while (u-- && !event_queue_handle->event_queue.empty()) {
+ vine_epoll_event *event = event_queue_handle->event_queue.front();
+ event_queue_handle->event_queue.pop();
+ if (event == NULL) {
+ VINE_LOGE("vine event queue is empty");
+ continue;
+ }
+
+ VINE_LOGD("Vine event[%p]", event);
+ if (event->handler == NULL) {
+ VINE_LOGI("No event handler");
+ continue;
+ }
+
+ event->handler(event->event_data, event->user_data);
+ if (event->free_func) {
+ event->free_func(event->event_data);
+ }
+ }
+
+ return VINE_ERROR_NONE;
+}
+
+vine_event_loop_fn vine_event_loop_epoll = {
+ .init = vine_event_loop_epoll_init,
+ .deinit = vine_event_loop_epoll_deinit,
+ .start = vine_event_loop_epoll_start,
+ .stop = vine_event_loop_epoll_stop,
+ .event_queue_create = vine_event_queue_epoll_create,
+ .event_queue_destroy = vine_event_queue_epoll_destroy,
+ .get_eventfd = vine_event_loop_epoll_get_eventfd,
+ .process = vine_event_loop_epoll_process,
+ .add_io_handler = vine_event_loop_epoll_add_io_handler,
+ .mod_io_handler = vine_event_loop_epoll_mod_io_handler,
+ .del_io_handler = vine_event_loop_epoll_del_io_handler,
+ .add_event = vine_event_loop_epoll_add_event,
+};
#include "vine.h"
#include "vine-event-loop.h"
-#include "vine-queue.h"
#include "vine-log.h"
#include "vine-utils.h"
-static pthread_t __vine_event_loop_tid = 0;
-
-static bool __cleanup = false;
-static int __vine_epoll_fd = 0;
-//static struct epoll_event __vine_epoll_events[MAX_VINE_EPOLL_EVENTS];
-//static int __vine_epoll_events_idx = 0;
-
-typedef struct {
- int fd;
- vine_poll_handler handler;
- void *user_data;
-} vine_io_event_handler;
-
-typedef struct {
- void *event_data;
- vine_event_handler handler;
- vine_event_free_handler free_func;
- void *user_data;
-} vine_event;
-
-typedef struct {
- int fd;
- VineQueue<vine_event *> event_queue;
-} vine_event_queue_s;
-
-#ifdef FD_SETSIZE
-#define MAX_IO_EVENT_HANDLERS FD_SETSIZE
-#else
-#define MAX_IO_EVENT_HANDLERS MAX_VINE_EPOLL_EVENTS
+static vine_event_loop_fn __event_loop;
+#if defined VINE_EVENT_LOOP_EPOLL
+extern vine_event_loop_fn vine_event_loop_epoll;
+#endif
+#if defined VINE_EVENT_LOOP_GLIB
#endif
-
-static vine_io_event_handler *io_event_handlers[MAX_IO_EVENT_HANDLERS] = {0, };
-
-static void *__vine_event_loop_run(void *arg)
-{
- VINE_LOGD("Run Vine event loop");
-
- struct epoll_event events[MAX_VINE_EPOLL_EVENTS];
- int timeout = -1;
-
- do {
- int n = epoll_wait(__vine_epoll_fd, events, MAX_VINE_EPOLL_EVENTS, timeout);
- if (n == -1) {
- VINE_LOGE("Invalid return value");
- break;
- }
-
- for (int i = 0; i < n; ++i) {
- vine_io_event_handler *h = (vine_io_event_handler *)events[i].data.ptr;
- if (h && h->handler)
- h->handler(h->fd, events[i].events, h->user_data);
- }
- } while (!__cleanup);
-
- // TODO:
- // Even although __cleanup is set as false,
- // this loop cannot be broken if waiting epoll_wait()
- // --> socketpair()? timeout?
-
- return NULL;
-}
int vine_event_loop_init()
{
- __vine_epoll_fd = epoll_create1(0);
- if (__vine_epoll_fd == -1) {
- VINE_LOGE("Fail to create epoll fd. error %d", errno);
- return VINE_ERROR_OPERATION_FAILED;
- }
-
- __cleanup = false;
+#if defined VINE_EVENT_LOOP_EPOLL
+ __event_loop = vine_event_loop_epoll;
+#endif
- return VINE_ERROR_NONE;
+ return __event_loop.init();
}
void vine_event_loop_deinit()
{
- close(__vine_epoll_fd);
+ __event_loop.deinit();
}
int vine_event_loop_start()
{
- VINE_LOGD("vine_event_loop_start");
- if (__vine_event_loop_tid) {
- VINE_LOGD("Vine event loop was already executed");
- return VINE_ERROR_NONE;
- }
-
- if (pthread_create(&__vine_event_loop_tid, NULL,
- __vine_event_loop_run, NULL) != 0) {
- VINE_LOGE("Fail to create event thread");
- return VINE_ERROR_OPERATION_FAILED;
- }
-
- // pthread_detach(__vine_event_loop_tid);
-
- return VINE_ERROR_NONE;
-}
-
-static void _vine_event_loop_wake_up()
-{
- uint64_t v = 1;
- int fd = eventfd(0, 0);
-
- VINE_LOGD("fd[%d] to wake the eventloop up", fd);
- vine_event_loop_add_io_handler(fd, VINE_POLLOUT, NULL, NULL);
- if (write(fd, &v, sizeof(v)) == -1)
- VINE_LOGE("Write error(%d)", errno);
+ return __event_loop.start();;
}
void vine_event_loop_stop()
{
- VINE_LOGD("vine_event_loop_stop");
- __cleanup = true;
- _vine_event_loop_wake_up();
- pthread_join(__vine_event_loop_tid, NULL);
- __vine_event_loop_tid = 0;
+ __event_loop.stop();;
}
-int vine_event_queue_create(vine_event_queue_h *event_fd)
+int vine_event_queue_create(vine_event_queue_h *event_queue)
{
- vine_event_queue_s *event_fd_handle = new vine_event_queue_s;
- VINE_LOGD("New Event Loop handle[%p]", event_fd_handle);
-
- *event_fd = event_fd_handle;
- event_fd_handle->fd = eventfd(0, 0);
- if (event_fd_handle->fd == -1) {
- VINE_LOGE("Fail to create eventfd. error %d", errno);
- delete event_fd_handle;
- return VINE_ERROR_OPERATION_FAILED;
- }
- VINE_LOGD("Event FD: %d", event_fd_handle->fd);
-
- return VINE_ERROR_NONE;
+ return __event_loop.event_queue_create(event_queue);;
}
-void vine_event_queue_destroy(vine_event_queue_h event_fd)
+void vine_event_queue_destroy(vine_event_queue_h event_queue)
{
- vine_event_queue_s *event_fd_handle = (vine_event_queue_s *)event_fd;
-
- vine_event *event = NULL;
- while(!event_fd_handle->event_queue.empty()) {
- event = event_fd_handle->event_queue.front();
- if (event && event->free_func)
- event->free_func(event->event_data);
- event_fd_handle->event_queue.pop();
- free(event);
- }
-
- if (event_fd_handle->fd >= 0)
- close(event_fd_handle->fd);
- delete event_fd_handle;
+ __event_loop.event_queue_destroy(event_queue);
}
-void vine_event_loop_get_eventfd(vine_event_queue_h event_fd, int *eventfd)
+void vine_event_loop_get_eventfd(vine_event_queue_h event_queue, int *eventfd)
{
- vine_event_queue_s *event_fd_handle = (vine_event_queue_s *)event_fd;
- *eventfd = event_fd_handle->fd;
-}
-
-static void _add_io_event_handler(int fd, vine_io_event_handler *h)
-{
- if (io_event_handlers[fd])
- free(io_event_handlers[fd]);
- io_event_handlers[fd] = h;
-}
-
-static void _del_io_event_handler(int fd)
-{
- if (io_event_handlers[fd]) {
- free(io_event_handlers[fd]);
- io_event_handlers[fd] = NULL;
- }
-}
-
-static vine_io_event_handler *_find_io_event_handler(int fd)
-{
- return io_event_handlers[fd];
+ __event_loop.get_eventfd(event_queue, eventfd);
}
int vine_event_loop_add_io_handler(
int fd, int events, vine_poll_handler handler, void *user_data)
{
- RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
- "fd should be equal to or greater than zero");
-
- vine_io_event_handler *h =
- (vine_io_event_handler *)calloc(1, sizeof(vine_io_event_handler));
- RET_VAL_IF(h == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
- h->fd = fd;
- h->handler = handler;
- h->user_data = user_data;
- _add_io_event_handler(fd, h);
-
- struct epoll_event event;
- event.events = events;
- event.data.ptr = (void *)h;
-
- epoll_ctl(__vine_epoll_fd, EPOLL_CTL_ADD, fd, &event);
- VINE_LOGD("Add an epoll event. fd: %d", fd);
-
- return VINE_ERROR_NONE;
+ return __event_loop.add_io_handler(fd, events, handler, user_data);
}
int vine_event_loop_mod_io_handler(
int fd, int events, vine_poll_handler handler, void *user_data)
{
- RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
- "fd should be equal to or greater than zero");
-
- struct epoll_event event;
- event.events = events;
- event.data.ptr = _find_io_event_handler(fd);
-
- epoll_ctl(__vine_epoll_fd, EPOLL_CTL_MOD, fd, &event);
- VINE_LOGD("Modify an epoll event. fd: %d event: %d", fd, events);
-
- return VINE_ERROR_NONE;
+ return __event_loop.mod_io_handler(fd, events, handler, user_data);
}
int vine_event_loop_del_io_handler(int fd)
{
- RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
- "fd should be equal to or greater than zero");
-
- epoll_ctl(__vine_epoll_fd, EPOLL_CTL_DEL, fd, NULL);
- _del_io_event_handler(fd);
- VINE_LOGD("Del an epoll event. fd: %d", fd);
-
- return VINE_ERROR_NONE;
+ return __event_loop.del_io_handler(fd);
}
// Register an event handler which is called in vine_event_loop_process()
// And then, an appropriate user callback will be called by the handler.
-int vine_event_loop_add_event(vine_event_queue_h event_fd, void *event_data,
+int vine_event_loop_add_event(vine_event_queue_h event_queue, void *event_data,
vine_event_handler handler, vine_event_free_handler free_func,
void *user_data)
{
- VINE_LOGD("event_data[%p] event_fd[%p]", event_data, event_fd);
- vine_event_queue_s *event_fd_handle = (vine_event_queue_s *)event_fd;
- RET_VAL_IF(event_fd == NULL, VINE_ERROR_INVALID_OPERATION, "event_fd is NULL");
-
- vine_event *event = (vine_event *)calloc(1, sizeof(vine_event));
- RET_VAL_IF(event == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
-
- event->event_data = event_data;
- event->handler = handler;
- event->free_func = free_func;
- event->user_data = user_data;
- VINE_LOGD("Vine event[%p]", event);
-
- event_fd_handle->event_queue.push(event);
-
- uint64_t u = 1;
- if (write(event_fd_handle->fd, &u, sizeof(uint64_t)) == -1) {
- VINE_LOGE("Write error(%d)", errno);
- return VINE_ERROR_OPERATION_FAILED;
- }
-
- return VINE_ERROR_NONE;
+ return __event_loop.add_event(event_queue, event_data, handler, free_func, user_data);
}
-int vine_event_loop_process(vine_event_queue_h event_fd)
+int vine_event_loop_process(vine_event_queue_h event_queue)
{
- VINE_LOGD("Process a vine event. event_fd[%p]", event_fd);
- vine_event_queue_s *event_fd_handle = (vine_event_queue_s *)event_fd;
- RET_VAL_IF(event_fd == NULL, VINE_ERROR_INVALID_OPERATION, "event_fd is NULL");
-
- uint64_t u;
- if (read(event_fd_handle->fd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) {
- VINE_LOGE("Read error(%d)", errno);
- return VINE_ERROR_OPERATION_FAILED;
- }
-
- VINE_LOGD("eventfd counter: %lld", u);
-
- while (u-- && !event_fd_handle->event_queue.empty()) {
- vine_event *event = event_fd_handle->event_queue.front();
- event_fd_handle->event_queue.pop();
- if (event == NULL) {
- VINE_LOGE("vine event queue is empty");
- continue;
- }
-
- VINE_LOGD("Vine event[%p]", event);
- if (event->handler == NULL) {
- VINE_LOGI("No event handler");
- continue;
- }
-
- event->handler(event->event_data, event->user_data);
- if (event->free_func) {
- event->free_func(event->event_data);
- }
- }
-
- return VINE_ERROR_NONE;
+ return __event_loop.process(event_queue);
}
using namespace std;
typedef struct {
- vine_event_queue_h event_fd;
+ vine_event_queue_h event_queue;
vine_discovery_method_e disc_method;
vine_disc_h disc_handle;
s->discovered = false;
s->disc_handle = NULL;
- int ret = vine_event_queue_create(&(s->event_fd));
+ int ret = vine_event_queue_create(&(s->event_queue));
if (ret != VINE_ERROR_NONE) {
VINE_LOGE("Fail to create eventfd %d", ret);
free(*session);
vine_session_s *s = (vine_session_s *)session;
VINE_LOGD("Destroy Session. session[%p]", session);
- vine_event_queue_destroy(s->event_fd);
+ vine_event_queue_destroy(s->event_queue);
vine_disc_destroy(s->disc_handle);
s->disc_handle = NULL;
free(session);
ret = vine_disc_publish(s->disc_handle, service, iface_name,
__published_cb, session,
- s->event_fd);
+ s->event_queue);
if (ret != VINE_ERROR_NONE) {
VINE_LOGE("Fail to vine_disc_publish");
vine_disc_destroy(s->disc_handle);
ret = vine_disc_subscribe(s->disc_handle, service_type, iface_name,
__discovered_cb, session,
- s->event_fd);
+ s->event_queue);
if (ret != VINE_ERROR_NONE) {
VINE_LOGE("Fail to vine_disc_subscribe");
vine_disc_destroy(s->disc_handle);
ret = vine_disc_resolve_ip(disc_handle, service,
__ip_resolved_cb, session,
- s->event_fd);
+ s->event_queue);
RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to vine_disc_resolve_ip");
return VINE_ERROR_NONE;
RET_VAL_IF(session == NULL, VINE_ERROR_INVALID_PARAMETER, "session is NULL");
vine_session_s *s = (vine_session_s *)session;
- *eq = s->event_fd;
+ *eq = s->event_queue;
return VINE_ERROR_NONE;
}
RET_VAL_IF(session == NULL, VINE_ERROR_INVALID_PARAMETER, "session is NULL");
vine_session_s *s = (vine_session_s *)session;
- vine_event_loop_get_eventfd(s->event_fd, fd);
+ vine_event_loop_get_eventfd(s->event_queue, fd);
return VINE_ERROR_NONE;
}
VINE_LOGD("Process event. session[%p]", session);
vine_session_s *s = (vine_session_s *)session;
- return vine_event_loop_process(s->event_fd);
+ return vine_event_loop_process(s->event_queue);
}