libmemif: refactor connection establishment
per_thread_ namespace fuctionality replaced by memif socket.
Interfaces are grouped by memif socket which holds interface database.
Each thread can create it's unique memif socket. The path name
can be equal across threads so that the app only uses one
UNIX socket. In case of listener socket, listener fd
can be obtained and set using APIs.
This change allows:
- No lookup on file descriptor events
- improves interrupt handling
- Loopback support (connect two interfaces in one app)
- usefull for debugging and testing
- Improves code readability by providing control channel
abstraction for each interface and listener sockets
Type: refactor
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
Change-Id: I1b8261042431c0376646ab4c4c831f6e59dd3eed
diff --git a/extras/libmemif/src/main.c b/extras/libmemif/src/main.c
index 967e033..6a8e8b9 100644
--- a/extras/libmemif/src/main.c
+++ b/extras/libmemif/src/main.c
@@ -65,8 +65,6 @@
#define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
#endif /* __x86_x64__ */
-libmemif_main_t libmemif_main;
-
static char memif_buf[MAX_ERRBUF_LEN];
const char *memif_errlist[ERRLIST_LEN] = { /* MEMIF_ERR_SUCCESS */
@@ -163,6 +161,7 @@
else
{
strlcpy (memif_buf, memif_errlist[err_code], sizeof (memif_buf));
+ memif_buf[strlen (memif_errlist[err_code])] = '\0';
}
return memif_buf;
}
@@ -173,6 +172,16 @@
return MEMIF_VERSION;
}
+const char *
+memif_get_version_str ()
+{
+#define __STR_HELPER(x) #x
+#define __STR(x) __STR_HELPER (x)
+ return __STR (MEMIF_VERSION_MAJOR) "." __STR (MEMIF_VERSION_MINOR);
+#undef __STR
+#undef __STR_HELPER
+}
+
#define DBG_TX_BUF (0)
#define DBG_RX_BUF (1)
@@ -231,398 +240,128 @@
return MEMIF_ERR_SYSCALL;
}
-/* Always valid */
-libmemif_main_t *
-get_libmemif_main (memif_socket_t * ms)
-{
- if (ms != NULL && ms->lm != NULL)
- return ms->lm;
- return &libmemif_main;
-}
-
static int
-memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
+memif_add_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde, uint32_t events)
{
- if (fd < 0)
+ if (fde.fd < 0)
{
- DBG ("invalid fd %d", fd);
+ DBG ("invalid fd %d", fde.fd);
return -1;
}
struct epoll_event evt;
memset (&evt, 0, sizeof (evt));
evt.events = events;
- evt.data.fd = fd;
- if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
+ evt.data.ptr = fde.private_ctx;
+ if (epoll_ctl (ms->epfd, EPOLL_CTL_ADD, fde.fd, &evt) < 0)
{
- DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
+ DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
return -1;
}
- DBG ("fd %d added to epoll", fd);
+ DBG ("fd %d added to epoll", fde.fd);
return 0;
}
static int
-memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
+memif_mod_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde, uint32_t events)
{
- if (fd < 0)
+ if (fde.fd < 0)
{
- DBG ("invalid fd %d", fd);
+ DBG ("invalid fd %d", fde.fd);
return -1;
}
struct epoll_event evt;
memset (&evt, 0, sizeof (evt));
evt.events = events;
- evt.data.fd = fd;
- if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
+ evt.data.ptr = fde.private_ctx;
+ if (epoll_ctl (ms->epfd, EPOLL_CTL_MOD, fde.fd, &evt) < 0)
{
- DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
+ DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
return -1;
}
- DBG ("fd %d modified on epoll", fd);
+ DBG ("fd %d modified on epoll", fde.fd);
return 0;
}
static int
-memif_del_epoll_fd (libmemif_main_t * lm, int fd)
+memif_del_epoll_fd (memif_socket_t *ms, memif_fd_event_t fde)
{
- if (fd < 0)
+ if (fde.fd < 0)
{
- DBG ("invalid fd %d", fd);
+ DBG ("invalid fd %d", fde.fd);
return -1;
}
struct epoll_event evt;
memset (&evt, 0, sizeof (evt));
- if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
+ if (epoll_ctl (ms->epfd, EPOLL_CTL_DEL, fde.fd, &evt) < 0)
{
- DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
+ DBG ("epoll_ctl: %s fd %d", strerror (errno), fde.fd);
return -1;
}
- DBG ("fd %d removed from epoll", fd);
+ DBG ("fd %d removed from epoll", fde.fd);
return 0;
}
int
-memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
+memif_control_fd_update (memif_fd_event_t fde, void *private_ctx)
{
- libmemif_main_t *lm;
+ memif_socket_t *ms = (memif_socket_t *) private_ctx;
+ int fd;
- lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
+ if (ms == NULL)
+ return MEMIF_ERR_INVAL_ARG;
- if (events & MEMIF_FD_EVENT_DEL)
- return memif_del_epoll_fd (lm, fd);
+ if (fde.type & MEMIF_FD_EVENT_DEL)
+ return memif_del_epoll_fd (ms, fde);
uint32_t evt = 0;
- if (events & MEMIF_FD_EVENT_READ)
+ if (fde.type & MEMIF_FD_EVENT_READ)
evt |= EPOLLIN;
- if (events & MEMIF_FD_EVENT_WRITE)
+ if (fde.type & MEMIF_FD_EVENT_WRITE)
evt |= EPOLLOUT;
- if (events & MEMIF_FD_EVENT_MOD)
- return memif_mod_epoll_fd (lm, fd, evt);
+ if (fde.type & MEMIF_FD_EVENT_MOD)
+ return memif_mod_epoll_fd (ms, fde, evt);
- return memif_add_epoll_fd (lm, fd, evt);
-}
-
-int
-add_list_elt (libmemif_main_t * lm, memif_list_elt_t * e,
- memif_list_elt_t ** list, uint16_t * len)
-{
- memif_list_elt_t *tmp;
- int i;
-
- for (i = 0; i < *len; i++)
- {
- if ((*list)[i].data_struct == NULL)
- {
- (*list)[i].key = e->key;
- (*list)[i].data_struct = e->data_struct;
- return i;
- }
- }
-
- tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
- if (tmp == NULL)
- return -1;
-
- for (i = *len; i < *len * 2; i++)
- {
- tmp[i].key = -1;
- tmp[i].data_struct = NULL;
- }
-
- tmp[*len].key = e->key;
- tmp[*len].data_struct = e->data_struct;
- i = *len;
- *len = *len * 2;
- *list = tmp;
-
- return i;
-}
-
-int
-get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
- int key)
-{
- int i;
- if (key == -1)
- {
- *e = NULL;
- return -1;
- }
-
- for (i = 0; i < len; i++)
- {
- if (list[i].key == key)
- {
- *e = &list[i];
- return 0;
- }
- }
- *e = NULL;
- return -1;
-}
-
-/* does not free memory, only marks element as free */
-int
-free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
-{
- int i;
- for (i = 0; i < len; i++)
- {
- if (list[i].key == key)
- {
- list[i].key = -1;
- list[i].data_struct = NULL;
- return 0;
- }
- }
-
- return -1;
-}
-
-int
-free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
- memif_connection_t * ctx)
-{
- int i;
- for (i = 0; i < len; i++)
- {
- if (list[i].key == -1)
- {
- if (list[i].data_struct == ctx)
- {
- list[i].data_struct = NULL;
- return 0;
- }
- }
- }
-
- return -1;
+ return memif_add_epoll_fd (ms, fde, evt);
}
static void
-memif_control_fd_update_register (libmemif_main_t * lm,
- memif_control_fd_update_t * cb)
+memif_control_fd_update_register (memif_socket_t *ms,
+ memif_control_fd_update_t *cb)
{
- lm->control_fd_update = cb;
+ ms->args.on_control_fd_update = cb;
}
void
-memif_register_external_region (memif_add_external_region_t * ar,
- memif_get_external_region_addr_t * gr,
- memif_del_external_region_t * dr,
- memif_get_external_buffer_offset_t * go)
+memif_register_external_region (memif_socket_handle_t sock,
+ memif_add_external_region_t *ar,
+ memif_get_external_region_addr_t *gr,
+ memif_del_external_region_t *dr,
+ memif_get_external_buffer_offset_t *go)
{
- libmemif_main_t *lm = &libmemif_main;
- lm->add_external_region = ar;
- lm->get_external_region_addr = gr;
- lm->del_external_region = dr;
- lm->get_external_buffer_offset = go;
+ memif_socket_t *ms = (memif_socket_t *) sock;
+ ms->add_external_region = ar;
+ ms->get_external_region_addr = gr;
+ ms->del_external_region = dr;
+ ms->get_external_buffer_offset = go;
}
static void
-memif_alloc_register (libmemif_main_t * lm, memif_alloc_t * ma)
+memif_alloc_register (memif_socket_t *ms, memif_alloc_t *ma)
{
- lm->alloc = ma;
+ ms->args.alloc = ma;
}
static void
-memif_realloc_register (libmemif_main_t * lm, memif_realloc_t * mr)
+memif_realloc_register (memif_socket_t *ms, memif_realloc_t *mr)
{
- lm->realloc = mr;
+ ms->args.realloc = mr;
}
static void
-memif_free_register (libmemif_main_t * lm, memif_free_t * mf)
+memif_free_register (memif_socket_t *ms, memif_free_t *mf)
{
- lm->free = mf;
-}
-
-int
-memif_set_connection_request_timer (struct itimerspec timer)
-{
- libmemif_main_t *lm = &libmemif_main;
- int err = MEMIF_ERR_SUCCESS;
-
- lm->arm = timer;
-
- /* overwrite timer, if already armed */
- if (lm->disconn_slaves != 0)
- {
- if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
- {
- err = memif_syscall_error_handler (errno);
- }
- }
- return err;
-}
-
-int
-memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
- memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
- memif_free_t * memif_free)
-{
- int err = MEMIF_ERR_SUCCESS; /* 0 */
- libmemif_main_t *lm = &libmemif_main;
- memset (lm, 0, sizeof (libmemif_main_t));
-
- /* register custom memory management */
- if (memif_alloc != NULL)
- {
- memif_alloc_register (lm, memif_alloc);
- }
- else
- memif_alloc_register (lm, malloc);
-
- if (memif_realloc != NULL)
- {
- memif_realloc_register (lm, memif_realloc);
- }
- else
- memif_realloc_register (lm, realloc);
-
- if (memif_free != NULL)
- memif_free_register (lm, memif_free);
- else
- memif_free_register (lm, free);
-
- if (app_name != NULL)
- {
- strlcpy ((char *) lm->app_name, app_name, sizeof (lm->app_name));
- }
- else
- {
- strlcpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
- sizeof (lm->app_name));
- }
-
- lm->poll_cancel_fd = -1;
- /* register control fd update callback */
- if (on_control_fd_update != NULL)
- memif_control_fd_update_register (lm, on_control_fd_update);
- else
- {
- lm->epfd = epoll_create (1);
- memif_control_fd_update_register (lm, memif_control_fd_update);
- if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
- {
- err = errno;
- DBG ("eventfd: %s", strerror (err));
- return memif_syscall_error_handler (err);
- }
- lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
- DBG ("libmemif event polling initialized");
- }
-
- lm->control_list_len = 2;
- lm->interrupt_list_len = 2;
- lm->socket_list_len = 1;
- lm->pending_list_len = 1;
-
- lm->control_list =
- lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
- if (lm->control_list == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- lm->interrupt_list =
- lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
- if (lm->interrupt_list == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- lm->socket_list =
- lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
- if (lm->socket_list == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
- lm->pending_list =
- lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
- if (lm->pending_list == NULL)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
-
- int i;
- for (i = 0; i < lm->control_list_len; i++)
- {
- lm->control_list[i].key = -1;
- lm->control_list[i].data_struct = NULL;
- }
- for (i = 0; i < lm->interrupt_list_len; i++)
- {
- lm->interrupt_list[i].key = -1;
- lm->interrupt_list[i].data_struct = NULL;
- }
- for (i = 0; i < lm->socket_list_len; i++)
- {
- lm->socket_list[i].key = -1;
- lm->socket_list[i].data_struct = NULL;
- }
- for (i = 0; i < lm->pending_list_len; i++)
- {
- lm->pending_list[i].key = -1;
- lm->pending_list[i].data_struct = NULL;
- }
-
- lm->disconn_slaves = 0;
-
- lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
- if (lm->timerfd < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
-
- lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
- lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
- lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
- lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
-
- if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, lm->private_ctx) < 0)
- {
- DBG ("callback type memif_control_fd_update_t error!");
- err = MEMIF_ERR_CB_FDUPDATE;
- goto error;
- }
-
- /* Create default socket */
- err = memif_create_socket ((memif_socket_handle_t *) &
- lm->default_socket,
- MEMIF_DEFAULT_SOCKET_PATH, NULL);
- if (err != MEMIF_ERR_SUCCESS)
- goto error;
-
- return err;
-
-error:
- memif_cleanup ();
- return err;
+ ms->args.free = mf;
}
static inline memif_ring_t *
@@ -658,122 +397,156 @@
return MEMIF_ERR_SUCCESS;
}
-static int
-memif_socket_start_listening (memif_socket_t * ms)
+int
+memif_poll_cancel_handler (memif_fd_event_type_t type, void *private_ctx)
{
- libmemif_main_t *lm = get_libmemif_main (ms);
- memif_list_elt_t elt;
- struct stat file_stat;
- struct sockaddr_un un = { 0 };
- int on = 1;
- int err = MEMIF_ERR_SUCCESS;
-
- if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
- return MEMIF_ERR_INVAL_ARG;
-
- /* check if file exists */
- if (stat ((char *) ms->filename, &file_stat) == 0)
- {
- if (S_ISSOCK (file_stat.st_mode))
- unlink ((char *) ms->filename);
- else
- return memif_syscall_error_handler (errno);
- }
-
- ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
- if (ms->fd < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
-
- DBG ("socket %d created", ms->fd);
- un.sun_family = AF_UNIX;
- strlcpy ((char *) un.sun_path, (char *) ms->filename, sizeof (un.sun_path));
- if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- if (listen (ms->fd, 1) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- if (stat ((char *) ms->filename, &file_stat) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
-
- /* add socket to libmemif main */
- elt.key = ms->fd;
- elt.data_struct = ms;
- add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
- /* if lm->private_ctx == lm event polling is done by libmemif */
- lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
-
- ms->type = MEMIF_SOCKET_TYPE_LISTENER;
-
- return err;
-
-error:
- if (ms->fd > 0)
- {
- close (ms->fd);
- ms->fd = -1;
- }
- return err;
+ return MEMIF_ERR_POLL_CANCEL;
}
int
-memif_create_socket (memif_socket_handle_t * sock, const char *filename,
+memif_connect_handler (memif_fd_event_type_t type, void *private_ctx)
+{
+ memif_socket_t *ms = (memif_socket_t *) private_ctx;
+ memif_connection_t *c;
+
+ /* loop ms->slave_interfaces and request connection for disconnected ones */
+ TAILQ_FOREACH (c, &ms->slave_interfaces, next)
+ {
+ /* connected or connecting */
+ if (c->control_channel != NULL)
+ continue;
+
+ /* ignore errors */
+ memif_request_connection (c);
+ }
+
+ return MEMIF_ERR_SUCCESS;
+}
+
+int
+memif_set_connection_request_timer (memif_socket_handle_t sock,
+ struct itimerspec timer)
+{
+ memif_socket_t *ms = (memif_socket_t *) sock;
+ memif_fd_event_t fde;
+ memif_fd_event_data_t *fdata;
+ void *ctx;
+
+ if (ms == NULL)
+ return MEMIF_ERR_INVAL_ARG;
+
+ if (ms->timer_fd < 0)
+ {
+ /* only create new timer if there is a valid interval */
+ if (timer.it_interval.tv_sec == 0 && timer.it_interval.tv_nsec == 0)
+ return MEMIF_ERR_SUCCESS;
+
+ /* create timerfd */
+ ms->timer_fd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
+ if (ms->timer_fd < 0)
+ return memif_syscall_error_handler (errno);
+
+ /* start listening for events */
+ fdata = ms->args.alloc (sizeof (*fdata));
+ fdata->event_handler = memif_connect_handler;
+ fdata->private_ctx = ms;
+
+ fde.fd = ms->timer_fd;
+ fde.type = MEMIF_FD_EVENT_READ;
+ fde.private_ctx = fdata;
+
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ ms->args.on_control_fd_update (fde, ctx);
+ }
+
+ ms->args.connection_request_timer = timer;
+
+ /* arm the timer */
+ if (timerfd_settime (ms->timer_fd, 0, &ms->args.connection_request_timer,
+ NULL) < 0)
+ return memif_syscall_error_handler (errno);
+
+ return MEMIF_ERR_SUCCESS;
+}
+
+int
+memif_create_socket (memif_socket_handle_t *sock, memif_socket_args_t *args,
void *private_ctx)
{
- libmemif_main_t *lm = &libmemif_main;
memif_socket_t *ms = (memif_socket_t *) * sock;
+ memif_fd_event_t fde;
+ memif_fd_event_data_t *fdata;
int i, err = MEMIF_ERR_SUCCESS;
-
- for (i = 0; i < lm->socket_list_len; i++)
- {
- if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
- {
- if (strncmp ((char *) ms->filename, filename,
- strlen ((char *) ms->filename)) == 0)
- return MEMIF_ERR_INVAL_ARG;
- }
- }
+ void *ctx;
/* allocate memif_socket_t */
ms = NULL;
- ms = lm->alloc (sizeof (memif_socket_t));
+ if (args->alloc != NULL)
+ ms = args->alloc (sizeof (memif_socket_t));
+ else
+ ms = malloc (sizeof (memif_socket_t));
if (ms == NULL)
{
err = MEMIF_ERR_NOMEM;
goto error;
}
+
+ /* default values */
memset (ms, 0, sizeof (memif_socket_t));
- /* set filename */
- memset (ms->filename, 0, sizeof (ms->filename));
- strlcpy ((char *) ms->filename, filename, sizeof (ms->filename));
+ ms->epfd = -1;
+ ms->listener_fd = -1;
+ ms->poll_cancel_fd = -1;
+ ms->timer_fd = -1;
- ms->type = MEMIF_SOCKET_TYPE_NONE;
+ /* copy arguments to internal struct */
+ memcpy (&ms->args, args, sizeof (*args));
+ /* Handle abstract socket by converting '@' -> '\0' */
+ if (ms->args.path[0] == '@')
+ ms->args.path[0] = '\0';
+ ms->private_ctx = private_ctx;
- ms->interface_list_len = 1;
- ms->interface_list =
- lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
- if (ms->interface_list == NULL)
+ if (ms->args.alloc == NULL)
+ memif_alloc_register (ms, malloc);
+ if (ms->args.realloc == NULL)
+ memif_realloc_register (ms, realloc);
+ if (ms->args.free == NULL)
+ memif_free_register (ms, free);
+
+ TAILQ_INIT (&ms->master_interfaces);
+ TAILQ_INIT (&ms->slave_interfaces);
+
+ /* FIXME: implement connection request timer */
+
+ /* initialize internal epoll */
+ if (ms->args.on_control_fd_update == NULL)
{
- err = MEMIF_ERR_NOMEM;
- goto error;
+ ms->epfd = epoll_create (1);
+ /* register default fd update callback */
+ memif_control_fd_update_register (ms, memif_control_fd_update);
+ ms->poll_cancel_fd = eventfd (0, EFD_NONBLOCK);
+ if (ms->poll_cancel_fd < 0)
+ {
+ err = errno;
+ DBG ("eventfd: %s", strerror (err));
+ return memif_syscall_error_handler (err);
+ }
+ /* add interrupt fd to epfd */
+ fdata = ms->args.alloc (sizeof (*fdata));
+ fdata->event_handler = memif_poll_cancel_handler;
+ fdata->private_ctx = ms;
+
+ fde.fd = ms->poll_cancel_fd;
+ fde.type = MEMIF_FD_EVENT_READ;
+ fde.private_ctx = fdata;
+
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ ms->args.on_control_fd_update (fde, ctx);
}
- ms->interface_list[0].key = -1;
- ms->interface_list[0].data_struct = NULL;
+
+ err =
+ memif_set_connection_request_timer (ms, ms->args.connection_request_timer);
+ if (err != MEMIF_ERR_SUCCESS)
+ goto error;
*sock = ms;
@@ -782,35 +555,86 @@
error:
if (ms != NULL)
{
- if (ms->fd > 0)
- {
- close (ms->fd);
- ms->fd = -1;
- }
- if (ms->interface_list != NULL)
- {
- lm->free (ms->interface_list);
- ms->interface_list = NULL;
- ms->interface_list_len = 0;
- }
- lm->free (ms);
- *sock = ms = NULL;
+ ms->args.free (ms);
+ if (ms->epfd != -1)
+ close (ms->epfd);
+ if (ms->poll_cancel_fd != -1)
+ close (ms->poll_cancel_fd);
}
return err;
}
+memif_socket_handle_t
+memif_get_socket_handle (memif_conn_handle_t conn)
+{
+ memif_connection_t *c = (memif_connection_t *) conn;
+
+ if (c == NULL)
+ return NULL;
+
+ return c->args.socket;
+}
+
+const char *
+memif_get_socket_path (memif_socket_handle_t sock)
+{
+ memif_socket_t *ms = (memif_socket_t *) sock;
+
+ if (ms == NULL)
+ return NULL;
+
+ return ms->args.path;
+}
int
-memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
- memif_connection_update_t * on_connect,
- memif_connection_update_t * on_disconnect,
- memif_interrupt_t * on_interrupt, void *private_ctx)
+memif_get_listener_fd (memif_socket_handle_t sock)
{
- libmemif_main_t *lm = get_libmemif_main (args->socket);
+ memif_socket_t *ms = (memif_socket_t *) sock;
+
+ if (ms == NULL)
+ return -1;
+
+ return ms->listener_fd;
+}
+
+int
+memif_set_listener_fd (memif_socket_handle_t sock, int fd)
+{
+ memif_socket_t *ms = (memif_socket_t *) sock;
+ memif_fd_event_t fde;
+ memif_fd_event_data_t *fdata;
+ void *ctx;
+
+ if ((ms == NULL) || (fd < 0))
+ return MEMIF_ERR_INVAL_ARG;
+
+ fdata = ms->args.alloc (sizeof (*fdata));
+ if (fdata == NULL)
+ return MEMIF_ERR_NOMEM;
+
+ ms->listener_fd = fd;
+
+ fdata->event_handler = memif_listener_handler;
+ fdata->private_ctx = ms;
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ /* send fd to epoll */
+ fde.fd = ms->listener_fd;
+ fde.type = MEMIF_FD_EVENT_READ;
+ fde.private_ctx = fdata;
+ ms->args.on_control_fd_update (fde, ctx);
+
+ return MEMIF_ERR_SUCCESS;
+}
+
+int
+memif_create (memif_conn_handle_t *c, memif_conn_args_t *args,
+ memif_connection_update_t *on_connect,
+ memif_connection_update_t *on_disconnect,
+ memif_on_interrupt_t *on_interrupt, void *private_ctx)
+{
int err, index = 0;
- memif_list_elt_t elt;
memif_connection_t *conn = (memif_connection_t *) * c;
- memif_socket_t *ms;
+ memif_socket_t *ms = (memif_socket_t *) args->socket;
if (conn != NULL)
{
@@ -818,7 +642,13 @@
return MEMIF_ERR_CONN;
}
- conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
+ if (ms == NULL)
+ {
+ DBG ("Missing memif socket");
+ return MEMIF_ERR_INVAL_ARG;
+ }
+
+ conn = (memif_connection_t *) ms->args.alloc (sizeof (*conn));
if (conn == NULL)
{
err = MEMIF_ERR_NOMEM;
@@ -848,92 +678,47 @@
conn->args.log2_ring_size = args->log2_ring_size;
conn->args.is_master = args->is_master;
conn->args.mode = args->mode;
- conn->msg_queue = NULL;
+ conn->args.socket = args->socket;
conn->regions = NULL;
conn->tx_queues = NULL;
conn->rx_queues = NULL;
- conn->fd = -1;
+ conn->control_channel = NULL;
conn->on_connect = on_connect;
conn->on_disconnect = on_disconnect;
conn->on_interrupt = on_interrupt;
conn->private_ctx = private_ctx;
memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
+ uint8_t l = sizeof (conn->args.interface_name);
strlcpy ((char *) conn->args.interface_name, (char *) args->interface_name,
- sizeof (conn->args.interface_name));
+ l);
- if ((strlen ((char *) args->secret)) > 0)
+ if ((l = strlen ((char *) args->secret)) > 0)
strlcpy ((char *) conn->args.secret, (char *) args->secret,
sizeof (conn->args.secret));
- if (args->socket != NULL)
- conn->args.socket = args->socket;
- else if (lm->default_socket != NULL)
- conn->args.socket = lm->default_socket;
+ if (args->is_master)
+ TAILQ_INSERT_TAIL (&ms->master_interfaces, conn, next);
else
+ TAILQ_INSERT_TAIL (&ms->slave_interfaces, conn, next);
+
+ err = memif_request_connection (conn);
+ if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_CONNREFUSED)
{
- err = MEMIF_ERR_INVAL_ARG;
+ if (args->is_master)
+ TAILQ_REMOVE (&ms->master_interfaces, conn, next);
+ else
+ TAILQ_REMOVE (&ms->slave_interfaces, conn, next);
goto error;
}
- ms = (memif_socket_t *) conn->args.socket;
-
- if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
- (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
- {
- err = MEMIF_ERR_INVAL_ARG;
- goto error;
- }
-
- elt.key = conn->args.interface_id;
- elt.data_struct = conn;
- add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
- ms->use_count++;
-
- if (conn->args.is_master)
- {
- if (ms->type == MEMIF_SOCKET_TYPE_NONE)
- {
- err = memif_socket_start_listening (ms);
- if (err != MEMIF_ERR_SUCCESS)
- goto error;
- }
- }
- else
- {
- elt.key = -1;
- elt.data_struct = conn;
- if ((index =
- add_list_elt (lm, &elt, &lm->control_list,
- &lm->control_list_len)) < 0)
- {
- err = MEMIF_ERR_NOMEM;
- goto error;
- }
-
- conn->index = index;
-
- /* try connecting to master */
- err = memif_request_connection (conn);
- if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
- {
- /* connection failed, arm reconnect timer (if not armed) */
- if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
- {
- err = memif_syscall_error_handler (errno);
- goto error;
- }
- }
- lm->disconn_slaves++;
- }
-
*c = conn;
return 0;
error:
if (conn != NULL)
- lm->free (conn);
+ ms->args.free (conn);
*c = conn = NULL;
return err;
}
@@ -942,23 +727,29 @@
memif_request_connection (memif_conn_handle_t c)
{
memif_connection_t *conn = (memif_connection_t *) c;
- libmemif_main_t *lm;
memif_socket_t *ms;
int err = MEMIF_ERR_SUCCESS;
int sockfd = -1;
- struct sockaddr_un sun;
+ struct sockaddr_un un = { 0 };
+ struct stat file_stat;
+ int on = 1;
+ memif_control_channel_t *cc = NULL;
+ memif_fd_event_t fde;
+ memif_fd_event_data_t *fdata = NULL;
+ void *ctx;
if (conn == NULL)
return MEMIF_ERR_NOCONN;
ms = (memif_socket_t *) conn->args.socket;
- lm = get_libmemif_main (ms);
-
- if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
- return MEMIF_ERR_INVAL_ARG;
- if (conn->fd > 0)
+ /* if control channel is assigned, the interface is either connected or
+ * connecting */
+ if (conn->control_channel != NULL)
return MEMIF_ERR_ALRCONN;
+ /* if interface is master and the socket is already listener we are done */
+ if (conn->args.is_master && (ms->listener_fd != -1))
+ return MEMIF_ERR_SUCCESS;
sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
if (sockfd < 0)
@@ -967,41 +758,90 @@
goto error;
}
- sun.sun_family = AF_UNIX;
+ un.sun_family = AF_UNIX;
- strlcpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path));
+ /* use memcpy to support abstract socket
+ * ms->args.path is already a valid socket path
+ */
+ memcpy (un.sun_path, ms->args.path, sizeof (un.sun_path) - 1);
- if (connect (sockfd, (struct sockaddr *) &sun,
- sizeof (struct sockaddr_un)) == 0)
+ /* allocate fd event data */
+ fdata = ms->args.alloc (sizeof (*fdata));
+ if (fdata == NULL)
{
- conn->fd = sockfd;
- conn->read_fn = memif_conn_fd_read_ready;
- conn->write_fn = memif_conn_fd_write_ready;
- conn->error_fn = memif_conn_fd_error;
-
- lm->control_list[conn->index].key = conn->fd;
- lm->control_fd_update (sockfd,
- MEMIF_FD_EVENT_READ |
- MEMIF_FD_EVENT_WRITE, lm->private_ctx);
-
- lm->disconn_slaves--;
- if (lm->disconn_slaves == 0)
- {
- if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
- {
- err = memif_syscall_error_handler (errno);
- return err;
- }
- }
- }
- else
- {
- err = memif_syscall_error_handler (errno);
- strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
+ err = MEMIF_ERR_NOMEM;
goto error;
}
- ms->type = MEMIF_SOCKET_TYPE_CLIENT;
+ if (conn->args.is_master != 0)
+ {
+ /* Configure socket optins */
+ if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (bind (sockfd, (struct sockaddr *) &un, sizeof (un)) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (listen (sockfd, 1) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ if (ms->args.path[0] != '\0')
+ {
+ /* Verify that the socket was created */
+ if (stat ((char *) ms->args.path, &file_stat) < 0)
+ {
+ err = memif_syscall_error_handler (errno);
+ goto error;
+ }
+ }
+
+ /* assign listener fd */
+ ms->listener_fd = sockfd;
+
+ fdata->event_handler = memif_listener_handler;
+ fdata->private_ctx = ms;
+ }
+ else
+ {
+ cc = ms->args.alloc (sizeof (*cc));
+ if (cc == NULL)
+ {
+ err = MEMIF_ERR_NOMEM;
+ goto error;
+ }
+ if (connect (sockfd, (struct sockaddr *) &un,
+ sizeof (struct sockaddr_un)) != 0)
+ {
+ err = MEMIF_ERR_CONNREFUSED;
+ goto error;
+ }
+
+ /* Create control channel */
+ cc->fd = sockfd;
+ cc->sock = ms;
+ cc->conn = conn;
+ TAILQ_INIT (&cc->msg_queue);
+
+ /* assign control channel to endpoint */
+ conn->control_channel = cc;
+
+ fdata->event_handler = memif_control_channel_handler;
+ fdata->private_ctx = cc;
+ }
+
+ /* if event polling is done internally, send memif socket as context */
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ /* send fd to epoll */
+ fde.fd = sockfd;
+ fde.type = MEMIF_FD_EVENT_READ;
+ fde.private_ctx = fdata;
+ ms->args.on_control_fd_update (fde, ctx);
return err;
@@ -1009,136 +849,55 @@
if (sockfd > 0)
close (sockfd);
sockfd = -1;
+ if (fdata != NULL)
+ ms->args.free (fdata);
+ fdata = NULL;
+ if (cc != NULL)
+ ms->args.free (cc);
+ conn->control_channel = cc = NULL;
return err;
}
int
-memif_control_fd_handler (int fd, uint8_t events)
+memif_control_fd_handler (void *ptr, memif_fd_event_type_t events)
{
- int i, err = MEMIF_ERR_SUCCESS; /* 0 */
- uint16_t num;
- memif_list_elt_t *e = NULL;
- memif_connection_t *conn;
- libmemif_main_t *lm = &libmemif_main;
- if (fd == lm->timerfd)
- {
- uint64_t b;
- ssize_t size;
- size = read (fd, &b, sizeof (b));
+ memif_fd_event_data_t *fdata = (memif_fd_event_data_t *) ptr;
- if (size == -1)
- goto error;
+ if (fdata == NULL)
+ return MEMIF_ERR_INVAL_ARG;
- for (i = 0; i < lm->control_list_len; i++)
- {
- if ((lm->control_list[i].key < 0)
- && (lm->control_list[i].data_struct != NULL))
- {
- conn = lm->control_list[i].data_struct;
- if (conn->args.is_master)
- continue;
- err = memif_request_connection (conn);
- if (err != MEMIF_ERR_SUCCESS)
- DBG ("memif_request_connection: %s", memif_strerror (err));
- }
- }
- }
- else
- {
- get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
- if (e != NULL)
- {
- if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
- {
- num =
- (((memif_connection_t *) e->data_struct)->
- args.is_master) ? ((memif_connection_t *) e->
- data_struct)->run_args.
- num_s2m_rings : ((memif_connection_t *) e->data_struct)->
- run_args.num_m2s_rings;
- for (i = 0; i < num; i++)
- {
- if (((memif_connection_t *) e->data_struct)->
- rx_queues[i].int_fd == fd)
- {
- ((memif_connection_t *) e->data_struct)->
- on_interrupt ((void *) e->data_struct,
- ((memif_connection_t *) e->
- data_struct)->private_ctx, i);
- return MEMIF_ERR_SUCCESS;
- }
- }
- }
- return MEMIF_ERR_SUCCESS;
- }
- get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
- if (e != NULL
- && ((memif_socket_t *) e->data_struct)->type ==
- MEMIF_SOCKET_TYPE_LISTENER)
- {
- err =
- memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
- return err;
- }
-
- get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
- if (e != NULL)
- {
- err = memif_read_ready (lm, fd);
- return err;
- }
-
- get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
- if (e != NULL)
- {
- if (events & MEMIF_FD_EVENT_READ)
- {
- err =
- ((memif_connection_t *) e->data_struct)->
- read_fn (e->data_struct);
- if (err != MEMIF_ERR_SUCCESS)
- return err;
- }
- if (events & MEMIF_FD_EVENT_WRITE)
- {
- err =
- ((memif_connection_t *) e->data_struct)->
- write_fn (e->data_struct);
- if (err != MEMIF_ERR_SUCCESS)
- return err;
- }
- if (events & MEMIF_FD_EVENT_ERROR)
- {
- err =
- ((memif_connection_t *) e->data_struct)->
- error_fn (e->data_struct);
- if (err != MEMIF_ERR_SUCCESS)
- return err;
- }
- }
- }
-
- return MEMIF_ERR_SUCCESS; /* 0 */
-
-error:
- return err;
+ return fdata->event_handler (events, fdata->private_ctx);
}
+int
+memif_interrupt_handler (memif_fd_event_type_t type, void *private_ctx)
+{
+ memif_interrupt_t *idata = (memif_interrupt_t *) private_ctx;
+
+ if (idata == NULL)
+ return MEMIF_ERR_INVAL_ARG;
+
+ return idata->c->on_interrupt (idata->c, idata->c->private_ctx, idata->qid);
+}
int
-memif_poll_event (int timeout)
+memif_poll_event (memif_socket_handle_t sock, int timeout)
{
- libmemif_main_t *lm = &libmemif_main;
+ memif_socket_t *ms = (memif_socket_t *) sock;
struct epoll_event evt;
int en = 0, err = MEMIF_ERR_SUCCESS; /* 0 */
- uint32_t events = 0;
+ memif_fd_event_type_t events = 0;
uint64_t counter = 0;
ssize_t r = 0;
+ sigset_t sigset;
+
+ if (ms == NULL)
+ return MEMIF_ERR_INVAL_ARG;
+
memset (&evt, 0, sizeof (evt));
evt.events = EPOLLIN | EPOLLOUT;
- sigset_t sigset;
sigemptyset (&sigset);
- en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
+ en = epoll_pwait (ms->epfd, &evt, 1, timeout, &sigset);
if (en < 0)
{
err = errno;
@@ -1147,51 +906,58 @@
}
if (en > 0)
{
- if (evt.data.fd == lm->poll_cancel_fd)
- {
- r = read (evt.data.fd, &counter, sizeof (counter));
- if (r == -1)
- return MEMIF_ERR_DISCONNECTED;
-
- return MEMIF_ERR_POLL_CANCEL;
- }
if (evt.events & EPOLLIN)
events |= MEMIF_FD_EVENT_READ;
if (evt.events & EPOLLOUT)
events |= MEMIF_FD_EVENT_WRITE;
if (evt.events & EPOLLERR)
events |= MEMIF_FD_EVENT_ERROR;
- err = memif_control_fd_handler (evt.data.fd, events);
- return err;
+ return memif_control_fd_handler (evt.data.ptr, events);
}
- return 0;
+ return MEMIF_ERR_SUCCESS;
}
int
-memif_cancel_poll_event ()
+memif_cancel_poll_event (memif_socket_handle_t sock)
{
- libmemif_main_t *lm = &libmemif_main;
+ memif_socket_t *ms = (memif_socket_t *) sock;
uint64_t counter = 1;
ssize_t w = 0;
- if (lm->poll_cancel_fd == -1)
- return 0;
- w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
+ if (ms->poll_cancel_fd == -1)
+ return MEMIF_ERR_INVAL_ARG;
+ w = write (ms->poll_cancel_fd, &counter, sizeof (counter));
if (w < sizeof (counter))
return MEMIF_ERR_INT_WRITE;
- return 0;
+ return MEMIF_ERR_SUCCESS;
}
-static void
-memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
+void
+memif_close_queues (memif_socket_t *ms, memif_queue_t *queues, int nqueues)
{
- if (*e == NULL)
- return;
- memif_msg_queue_free (lm, &(*e)->next);
- lm->free (*e);
- *e = NULL;
- return;
+ memif_fd_event_t fde;
+ memif_queue_t *mq;
+ void *ctx;
+
+ int i;
+ for (i = 0; i < nqueues; i++)
+ {
+ mq = &queues[i];
+ if (mq != NULL)
+ {
+ if (mq->int_fd > 0)
+ {
+ /* Stop listening for events */
+ fde.fd = mq->int_fd;
+ fde.type = MEMIF_FD_EVENT_DEL;
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ ms->args.on_control_fd_update (fde, ctx);
+ close (mq->int_fd);
+ }
+ mq->int_fd = -1;
+ }
+ }
}
/* send disconnect msg and close interface */
@@ -1200,85 +966,43 @@
{
int err = MEMIF_ERR_SUCCESS, i; /* 0 */
memif_queue_t *mq;
- libmemif_main_t *lm;
- memif_list_elt_t *e;
-
- if (c == NULL)
- {
- DBG ("no connection");
- return MEMIF_ERR_NOCONN;
- }
-
- lm = get_libmemif_main (c->args.socket);
+ memif_socket_t *ms = (memif_socket_t *) c->args.socket;
+ memif_fd_event_t fde;
+ void *ctx;
c->on_disconnect ((void *) c, c->private_ctx);
- if (c->fd > 0)
- {
- memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
- lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
- close (c->fd);
- }
- get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
- if (e != NULL)
- {
- if (c->args.is_master)
- free_list_elt (lm->control_list, lm->control_list_len, c->fd);
- e->key = c->fd = -1;
- }
+ /* Delete control channel */
+ if (c->control_channel != NULL)
+ memif_delete_control_channel (c->control_channel);
if (c->tx_queues != NULL)
{
- for (i = 0; i < c->tx_queues_num; i++)
- {
- mq = &c->tx_queues[i];
- if (mq != NULL)
- {
- if (mq->int_fd > 0)
- close (mq->int_fd);
- free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
- mq->int_fd);
- mq->int_fd = -1;
- }
- }
- lm->free (c->tx_queues);
+ memif_close_queues (ms, c->tx_queues, c->tx_queues_num);
+ ms->args.free (c->tx_queues);
c->tx_queues = NULL;
}
c->tx_queues_num = 0;
if (c->rx_queues != NULL)
{
- for (i = 0; i < c->rx_queues_num; i++)
- {
- mq = &c->rx_queues[i];
- if (mq != NULL)
- {
- if (mq->int_fd > 0)
- {
- if (c->on_interrupt != NULL)
- lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
- lm->private_ctx);
- close (mq->int_fd);
- }
- free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
- mq->int_fd);
- mq->int_fd = -1;
- }
- }
- lm->free (c->rx_queues);
+ memif_close_queues (ms, c->rx_queues, c->rx_queues_num);
+ ms->args.free (c->rx_queues);
c->rx_queues = NULL;
}
c->rx_queues_num = 0;
+ /* TODO: Slave reuse regions */
+
for (i = 0; i < c->regions_num; i++)
{
if (&c->regions[i] == NULL)
continue;
if (c->regions[i].is_external != 0)
{
- lm->del_external_region (c->regions[i].addr,
- c->regions[i].region_size,
- c->regions[i].fd, c->private_ctx);
+ ms->del_external_region (c->regions[i].addr,
+ c->regions[i].region_size, c->regions[i].fd,
+ c->private_ctx);
}
else
{
@@ -1289,27 +1013,12 @@
c->regions[i].fd = -1;
}
}
- lm->free (c->regions);
+ ms->args.free (c->regions);
c->regions = NULL;
c->regions_num = 0;
memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
- memif_msg_queue_free (lm, &c->msg_queue);
-
- if (!(c->args.is_master))
- {
- if (lm->disconn_slaves == 0)
- {
- if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
- {
- err = memif_syscall_error_handler (errno);
- DBG ("timerfd_settime: arm");
- }
- }
- lm->disconn_slaves++;
- }
-
return err;
}
@@ -1321,24 +1030,44 @@
if (ms == NULL)
return NULL;
- return (char *) ms->filename;
+ return (char *) ms->args.path;
}
int
memif_delete_socket (memif_socket_handle_t * sock)
{
memif_socket_t *ms = (memif_socket_t *) * sock;
- libmemif_main_t *lm;
+ memif_fd_event_t fde;
+ void *ctx;
/* check if socket is in use */
- if (ms == NULL || ms->use_count > 0)
+ if (ms == NULL || !TAILQ_EMPTY (&ms->master_interfaces) ||
+ !TAILQ_EMPTY (&ms->slave_interfaces))
return MEMIF_ERR_INVAL_ARG;
- lm = get_libmemif_main (ms);
+ if (ms->listener_fd > 0)
+ {
+ fde.fd = ms->listener_fd;
+ fde.type = MEMIF_FD_EVENT_DEL;
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ ms->args.on_control_fd_update (fde, ctx);
+ }
+ ms->listener_fd = -1;
- lm->free (ms->interface_list);
- ms->interface_list = NULL;
- lm->free (ms);
+ if (ms->poll_cancel_fd > 0)
+ {
+ fde.fd = ms->poll_cancel_fd;
+ fde.type = MEMIF_FD_EVENT_DEL;
+ ctx = ms->epfd != -1 ? ms : ms->private_ctx;
+ ms->args.on_control_fd_update (fde, ctx);
+ }
+ ms->poll_cancel_fd = -1;
+
+ if (ms->epfd > 0)
+ close (ms->epfd);
+ ms->epfd = -1;
+
+ ms->args.free (ms);
*sock = ms = NULL;
return MEMIF_ERR_SUCCESS;
@@ -1348,8 +1077,7 @@
memif_delete (memif_conn_handle_t * conn)
{
memif_connection_t *c = (memif_connection_t *) * conn;
- libmemif_main_t *lm;
- memif_socket_t *ms = NULL;
+ memif_socket_t *ms;
int err = MEMIF_ERR_SUCCESS;
if (c == NULL)
@@ -1358,50 +1086,17 @@
return MEMIF_ERR_NOCONN;
}
- if (c->fd > 0)
- {
- DBG ("DISCONNECTING");
- err = memif_disconnect_internal (c);
- if (err == MEMIF_ERR_NOCONN)
- return err;
- }
-
- lm = get_libmemif_main (c->args.socket);
-
- free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
+ err = memif_disconnect_internal (c);
ms = (memif_socket_t *) c->args.socket;
- ms->use_count--;
- free_list_elt (ms->interface_list, ms->interface_list_len,
- c->args.interface_id);
- if (ms->use_count <= 0)
- {
- /* stop listening on this socket */
- if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
- {
- lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
- free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
- close (ms->fd);
- ms->fd = -1;
- }
- /* socket not in use */
- ms->type = MEMIF_SOCKET_TYPE_NONE;
- }
- if (!c->args.is_master)
- {
- lm->disconn_slaves--;
- if (lm->disconn_slaves <= 0)
- {
- if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
- {
- err = memif_syscall_error_handler (errno);
- DBG ("timerfd_settime: disarm");
- }
- }
- }
+ if (c->args.is_master)
+ TAILQ_REMOVE (&ms->master_interfaces, c, next);
+ else
+ TAILQ_REMOVE (&ms->slave_interfaces, c, next);
+ /* TODO: don't listen with empty interface queue */
- lm->free (c);
+ ms->args.free (c);
c = NULL;
*conn = c;
@@ -1411,7 +1106,7 @@
int
memif_connect1 (memif_connection_t * c)
{
- libmemif_main_t *lm;
+ memif_socket_t *ms;
memif_region_t *mr;
memif_queue_t *mq;
int i;
@@ -1419,7 +1114,7 @@
if (c == NULL)
return MEMIF_ERR_INVAL_ARG;
- lm = get_libmemif_main (c->args.socket);
+ ms = (memif_socket_t *) c->args.socket;
for (i = 0; i < c->regions_num; i++)
{
@@ -1430,11 +1125,10 @@
{
if (mr->is_external)
{
- if (lm->get_external_region_addr == NULL)
+ if (ms->get_external_region_addr == NULL)
return MEMIF_ERR_INVAL_ARG;
- mr->addr =
- lm->get_external_region_addr (mr->region_size, mr->fd,
- c->private_ctx);
+ mr->addr = ms->get_external_region_addr (
+ mr->region_size, mr->fd, c->private_ctx);
}
else
{
@@ -1442,8 +1136,8 @@
return MEMIF_ERR_NO_SHMFD;
if ((mr->addr =
- mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
+ mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
{
return memif_syscall_error_handler (errno);
}
@@ -1482,21 +1176,17 @@
}
}
- lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
- lm->private_ctx);
-
return 0;
}
static inline int
-memif_add_region (libmemif_main_t * lm, memif_connection_t * conn,
- uint8_t has_buffers)
+memif_add_region (memif_connection_t *conn, uint8_t has_buffers)
{
memif_region_t *r;
+ memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
- r =
- lm->realloc (conn->regions,
- sizeof (memif_region_t) * ++conn->regions_num);
+ r = ms->args.realloc (conn->regions,
+ sizeof (memif_region_t) * ++conn->regions_num);
if (r == NULL)
return MEMIF_ERR_NOMEM;
@@ -1539,10 +1229,11 @@
}
static inline int
-memif_init_queues (libmemif_main_t * lm, memif_connection_t * conn)
+memif_init_queues (memif_connection_t *conn)
{
int i, j;
memif_ring_t *ring;
+ memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
for (i = 0; i < conn->run_args.num_s2m_rings; i++)
{
@@ -1580,23 +1271,17 @@
}
}
memif_queue_t *mq;
- DBG ("alloc: %p", lm->alloc);
- DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
- mq =
- (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
- conn->run_args.num_s2m_rings);
+ mq = (memif_queue_t *) ms->args.alloc (sizeof (memif_queue_t) *
+ conn->run_args.num_s2m_rings);
if (mq == NULL)
return MEMIF_ERR_NOMEM;
int x;
- memif_list_elt_t e;
+
for (x = 0; x < conn->run_args.num_s2m_rings; x++)
{
if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
return memif_syscall_error_handler (errno);
- e.key = mq[x].int_fd;
- e.data_struct = conn;
- add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
DBG ("RING: %p I: %d", mq[x].ring, x);
@@ -1610,9 +1295,8 @@
conn->tx_queues = mq;
conn->tx_queues_num = conn->run_args.num_s2m_rings;
- mq =
- (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
- conn->run_args.num_m2s_rings);
+ mq = (memif_queue_t *) ms->args.alloc (sizeof (memif_queue_t) *
+ conn->run_args.num_m2s_rings);
if (mq == NULL)
return MEMIF_ERR_NOMEM;
@@ -1620,9 +1304,6 @@
{
if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
return memif_syscall_error_handler (errno);
- e.key = mq[x].int_fd;
- e.data_struct = conn;
- add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
DBG ("RING: %p I: %d", mq[x].ring, x);
@@ -1643,23 +1324,16 @@
memif_init_regions_and_queues (memif_connection_t * conn)
{
memif_region_t *r;
- libmemif_main_t *lm;
-
- if (conn == NULL)
- return MEMIF_ERR_INVAL_ARG;
-
- lm = get_libmemif_main (conn->args.socket);
+ memif_socket_t *ms = (memif_socket_t *) conn->args.socket;
/* region 0. rings */
- memif_add_region (lm, conn, /* has_buffers */ 0);
+ memif_add_region (conn, /* has_buffers */ 0);
/* region 1. buffers */
- if (lm->add_external_region)
+ if (ms->add_external_region)
{
- r =
- (memif_region_t *) lm->realloc (conn->regions,
- sizeof (memif_region_t) *
- ++conn->regions_num);
+ r = (memif_region_t *) ms->args.realloc (
+ conn->regions, sizeof (memif_region_t) * ++conn->regions_num);
if (r == NULL)
return MEMIF_ERR_NOMEM;
conn->regions = r;
@@ -1668,17 +1342,17 @@
conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
(conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
conn->regions[1].buffer_offset = 0;
- lm->add_external_region (&conn->regions[1].addr,
+ ms->add_external_region (&conn->regions[1].addr,
conn->regions[1].region_size,
&conn->regions[1].fd, conn->private_ctx);
conn->regions[1].is_external = 1;
}
else
{
- memif_add_region (lm, conn, 1);
+ memif_add_region (conn, 1);
}
- memif_init_queues (lm, conn);
+ memif_init_queues (conn);
return 0;
}
@@ -1772,7 +1446,7 @@
memif_connection_t *c = (memif_connection_t *) conn;
if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (EXPECT_FALSE (c->fd < 0))
+ if (EXPECT_FALSE (c->control_channel == NULL))
return MEMIF_ERR_DISCONNECTED;
if (EXPECT_FALSE (qid >= c->tx_queues_num))
return MEMIF_ERR_QID;
@@ -1833,7 +1507,7 @@
memif_connection_t *c = (memif_connection_t *) conn;
if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (EXPECT_FALSE (c->fd < 0))
+ if (EXPECT_FALSE (c->control_channel == NULL))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
(c->args.is_master) ? c->run_args.num_m2s_rings : c->
@@ -1843,7 +1517,7 @@
if (EXPECT_FALSE (!count_out))
return MEMIF_ERR_INVAL_ARG;
- libmemif_main_t *lm = get_libmemif_main (c->args.socket);
+ memif_socket_t *ms = (memif_socket_t *) c->args.socket;
memif_queue_t *mq = &c->tx_queues[qid];
memif_ring_t *ring = mq->ring;
memif_buffer_t *b0;
@@ -1855,6 +1529,7 @@
uint16_t dst_left, src_left;
uint16_t saved_count;
uint16_t saved_next_buf;
+ uint16_t slot;
memif_buffer_t *saved_b;
*count_out = 0;
@@ -1917,9 +1592,9 @@
/* slave resets buffer offset */
if (c->args.is_master == 0)
{
- memif_desc_t *d = &ring->desc[mq->next_buf & mask];
- if (lm->get_external_buffer_offset)
- d->offset = lm->get_external_buffer_offset (c->private_ctx);
+ memif_desc_t *d = &ring->desc[slot & mask];
+ if (ms->get_external_buffer_offset)
+ d->offset = ms->get_external_buffer_offset (c->private_ctx);
else
d->offset = d->offset - (d->offset & offset_mask);
}
@@ -1956,14 +1631,14 @@
memif_connection_t *c = (memif_connection_t *) conn;
if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (EXPECT_FALSE (c->fd < 0))
+ if (EXPECT_FALSE (c->control_channel == NULL))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
(c->args.is_master) ? c->run_args.num_s2m_rings : c->
run_args.num_m2s_rings;
if (EXPECT_FALSE (qid >= num))
return MEMIF_ERR_QID;
- libmemif_main_t *lm = get_libmemif_main (c->args.socket);
+ memif_socket_t *ms = (memif_socket_t *) c->args.socket;
memif_queue_t *mq = &c->rx_queues[qid];
memif_ring_t *ring = mq->ring;
uint16_t mask = (1 << mq->log2_ring_size) - 1;
@@ -1990,8 +1665,8 @@
d = &ring->desc[slot & mask];
d->region = 1;
d->length = c->run_args.buffer_size - headroom;
- if (lm->get_external_buffer_offset)
- d->offset = lm->get_external_buffer_offset (c->private_ctx);
+ if (ms->get_external_buffer_offset)
+ d->offset = ms->get_external_buffer_offset (c->private_ctx);
else
d->offset = d->offset - (d->offset & offset_mask) + headroom;
slot++;
@@ -2011,7 +1686,7 @@
memif_connection_t *c = (memif_connection_t *) conn;
if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (EXPECT_FALSE (c->fd < 0))
+ if (EXPECT_FALSE (c->control_channel == NULL))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
(c->args.is_master) ? c->run_args.num_m2s_rings : c->
@@ -2112,7 +1787,7 @@
memif_connection_t *c = (memif_connection_t *) conn;
if (EXPECT_FALSE (c == NULL))
return MEMIF_ERR_NOCONN;
- if (EXPECT_FALSE (c->fd < 0))
+ if (EXPECT_FALSE (c->control_channel == NULL))
return MEMIF_ERR_DISCONNECTED;
uint8_t num =
(c->args.is_master) ? c->run_args.num_s2m_rings : c->
@@ -2202,7 +1877,6 @@
char *buf, ssize_t buflen)
{
memif_connection_t *c = (memif_connection_t *) conn;
- libmemif_main_t *lm;
memif_socket_t *ms;
int err = MEMIF_ERR_SUCCESS, i;
ssize_t l0 = 0, l1;
@@ -2211,7 +1885,6 @@
return MEMIF_ERR_NOCONN;
ms = (memif_socket_t *) c->args.socket;
- lm = get_libmemif_main (ms);
l1 = strlen ((char *) c->args.interface_name);
if (l0 + l1 < buflen)
@@ -2223,10 +1896,11 @@
else
err = MEMIF_ERR_NOBUF_DET;
- l1 = strlen ((char *) lm->app_name);
+ l1 = strlen ((char *) ms->args.app_name);
if (l0 + l1 < buflen)
{
- md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
+ md->inst_name =
+ (uint8_t *) strcpy (buf + l0, (char *) ms->args.app_name);
l0 += l1 + 1;
}
else
@@ -2269,12 +1943,15 @@
md->role = (c->args.is_master) ? 0 : 1;
md->mode = c->args.mode;
- l1 = strlen ((char *) ms->filename);
+ l1 = 108;
if (l0 + l1 < buflen)
{
- md->socket_filename =
- (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
- l0 += l1 + 1;
+ md->socket_path = (uint8_t *) memcpy (buf + l0, ms->args.path, 108);
+ if (md->socket_path[0] == '\0')
+ {
+ md->socket_path[0] = '@';
+ }
+ l0 += l1;
}
else
err = MEMIF_ERR_NOBUF_DET;
@@ -2353,7 +2030,9 @@
else
err = MEMIF_ERR_NOBUF_DET;
- md->link_up_down = (c->fd > 0) ? 1 : 0;
+ /* This is not completely true, clients should relay on
+ * on_connect/on_disconnect callbacks */
+ md->link_up_down = (c->control_channel != NULL) ? 1 : 0;
return err; /* 0 */
}
@@ -2367,7 +2046,7 @@
*efd = -1;
if (c == NULL)
return MEMIF_ERR_NOCONN;
- if (c->fd < 0)
+ if (c->control_channel == NULL)
return MEMIF_ERR_DISCONNECTED;
num =
@@ -2380,31 +2059,3 @@
return MEMIF_ERR_SUCCESS;
}
-
-int
-memif_cleanup ()
-{
- libmemif_main_t *lm = &libmemif_main;
- int err;
-
- err = memif_delete_socket ((memif_socket_handle_t *) & lm->default_socket);
- if (err != MEMIF_ERR_SUCCESS)
- return err;
-
- if (lm->control_list)
- lm->free (lm->control_list);
- lm->control_list = NULL;
- if (lm->interrupt_list)
- lm->free (lm->interrupt_list);
- lm->interrupt_list = NULL;
- if (lm->socket_list)
- lm->free (lm->socket_list);
- lm->socket_list = NULL;
- if (lm->pending_list)
- lm->free (lm->pending_list);
- lm->pending_list = NULL;
- if (lm->poll_cancel_fd != -1)
- close (lm->poll_cancel_fd);
-
- return MEMIF_ERR_SUCCESS; /* 0 */
-}