libmemif: Connection request APIs
Add APIs that allow changing reconnect timer and request connection. First connection request is automatically sent once slave interface is created. Change-Id: Ie3558b7b94a780b046755f7f0ac6c3dcf07633e4 Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
608996d2bd
commit
84b83776d3
@ -23,11 +23,12 @@
|
|||||||
#define _LIBMEMIF_H_
|
#define _LIBMEMIF_H_
|
||||||
|
|
||||||
/** Libmemif version. */
|
/** Libmemif version. */
|
||||||
#define LIBMEMIF_VERSION "2.0"
|
#define LIBMEMIF_VERSION "2.1"
|
||||||
/** Default name of application using libmemif. */
|
/** Default name of application using libmemif. */
|
||||||
#define MEMIF_DEFAULT_APP_NAME "libmemif-app"
|
#define MEMIF_DEFAULT_APP_NAME "libmemif-app"
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
|
||||||
/*! Error codes */
|
/*! Error codes */
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -49,7 +50,7 @@ typedef enum
|
|||||||
MEMIF_ERR_NOCONN, /*!< handle points to no connection */
|
MEMIF_ERR_NOCONN, /*!< handle points to no connection */
|
||||||
MEMIF_ERR_CONN, /*!< handle points to existing connection */
|
MEMIF_ERR_CONN, /*!< handle points to existing connection */
|
||||||
MEMIF_ERR_CB_FDUPDATE, /*!< user defined callback memif_control_fd_update_t error */
|
MEMIF_ERR_CB_FDUPDATE, /*!< user defined callback memif_control_fd_update_t error */
|
||||||
MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket filename
|
MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket filename
|
||||||
exists, but it's not socket */
|
exists, but it's not socket */
|
||||||
MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */
|
MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */
|
||||||
MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */
|
MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */
|
||||||
@ -419,7 +420,7 @@ int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
|
|||||||
@param err_code - error code
|
@param err_code - error code
|
||||||
|
|
||||||
Converts error code to error message.
|
Converts error code to error message.
|
||||||
|
|
||||||
\return Error string
|
\return Error string
|
||||||
*/
|
*/
|
||||||
char *memif_strerror (int err_code);
|
char *memif_strerror (int err_code);
|
||||||
@ -475,13 +476,13 @@ int memif_cleanup ();
|
|||||||
@param private_ctx - private contex passed back to user with callback
|
@param private_ctx - private contex passed back to user with callback
|
||||||
|
|
||||||
Creates memory interface.
|
Creates memory interface.
|
||||||
|
|
||||||
SLAVE-MODE -
|
SLAVE-MODE -
|
||||||
Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
|
Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
|
||||||
every disconnected memif in slave mode will send connection request.
|
every disconnected memif in slave mode will send connection request.
|
||||||
On success new fd is passed to user with memif_control_fd_update_t.
|
On success new fd is passed to user with memif_control_fd_update_t.
|
||||||
|
|
||||||
MASTER-MODE -
|
MASTER-MODE -
|
||||||
Create listener socket and pass fd to user with memif_cntrol_fd_update_t.
|
Create listener socket and pass fd to user with memif_cntrol_fd_update_t.
|
||||||
If this fd is passed to memif_control_fd_handler accept will be called and
|
If this fd is passed to memif_control_fd_handler accept will be called and
|
||||||
new fd will be passed to user with memif_control_fd_update_t.
|
new fd will be passed to user with memif_control_fd_update_t.
|
||||||
@ -500,15 +501,15 @@ int memif_create (memif_conn_handle_t * conn, memif_conn_args_t * args,
|
|||||||
|
|
||||||
If event occures on any control fd, call memif_control_fd_handler.
|
If event occures on any control fd, call memif_control_fd_handler.
|
||||||
Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly.
|
Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly.
|
||||||
|
|
||||||
FD-TYPE -
|
FD-TYPE -
|
||||||
TIMERFD -
|
TIMERFD -
|
||||||
Every disconnected memif in slave mode will request connection.
|
Every disconnected memif in slave mode will request connection.
|
||||||
LISTENER or CONTROL -
|
LISTENER or CONTROL -
|
||||||
Handle socket messaging (internal connection establishment).
|
Handle socket messaging (internal connection establishment).
|
||||||
INTERRUPT -
|
INTERRUPT -
|
||||||
Call on_interrupt callback (if set).
|
Call on_interrupt callback (if set).
|
||||||
|
|
||||||
\return memif_err_t
|
\return memif_err_t
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -593,7 +594,7 @@ int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
|
|||||||
/** \brief Memif poll event
|
/** \brief Memif poll event
|
||||||
@param timeout - timeout in seconds
|
@param timeout - timeout in seconds
|
||||||
|
|
||||||
Passive event polling -
|
Passive event polling -
|
||||||
timeout = 0 - dont wait for event, check event queue if there is an event and return.
|
timeout = 0 - dont wait for event, check event queue if there is an event and return.
|
||||||
timeout = -1 - wait until event
|
timeout = -1 - wait until event
|
||||||
|
|
||||||
@ -615,6 +616,25 @@ int memif_poll_event (int timeout);
|
|||||||
*/
|
*/
|
||||||
#define MEMIF_HAVE_CANCEL_POLL_EVENT 1
|
#define MEMIF_HAVE_CANCEL_POLL_EVENT 1
|
||||||
int memif_cancel_poll_event ();
|
int memif_cancel_poll_event ();
|
||||||
|
|
||||||
|
/** \brief Set connection request timer value
|
||||||
|
@param timer - new timer value
|
||||||
|
|
||||||
|
Timer on which all disconnected slaves request connection.
|
||||||
|
See system call 'timer_settime' man-page.
|
||||||
|
|
||||||
|
\return memif_err_t
|
||||||
|
*/
|
||||||
|
int memif_set_connection_request_timer(struct itimerspec timer);
|
||||||
|
|
||||||
|
/** \brief Send connection request
|
||||||
|
@param conn - memif connection handle
|
||||||
|
|
||||||
|
Only slave interface can request connection.
|
||||||
|
|
||||||
|
\return memif_err_t
|
||||||
|
*/
|
||||||
|
int memif_request_connection(memif_conn_handle_t conn);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* _LIBMEMIF_H_ */
|
#endif /* _LIBMEMIF_H_ */
|
||||||
|
@ -451,6 +451,25 @@ memif_free_register (memif_free_t * mf)
|
|||||||
lm->free = 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
|
int
|
||||||
memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
|
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_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
|
||||||
@ -573,10 +592,10 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
lm->arm.it_value.tv_sec = 2;
|
lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
|
||||||
lm->arm.it_value.tv_nsec = 0;
|
lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
|
||||||
lm->arm.it_interval.tv_sec = 2;
|
lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
|
||||||
lm->arm.it_interval.tv_nsec = 0;
|
lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
|
||||||
|
|
||||||
if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
|
if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0)
|
||||||
{
|
{
|
||||||
@ -851,15 +870,6 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lm->disconn_slaves == 0)
|
|
||||||
{
|
|
||||||
if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
|
|
||||||
{
|
|
||||||
err = memif_syscall_error_handler (errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lm->disconn_slaves++;
|
lm->disconn_slaves++;
|
||||||
|
|
||||||
list_elt.key = -1;
|
list_elt.key = -1;
|
||||||
@ -871,9 +881,21 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
|
|||||||
err = MEMIF_ERR_NOMEM;
|
err = MEMIF_ERR_NOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
conn->index = index;
|
conn->index = index;
|
||||||
|
|
||||||
|
/* try connectiong to master */
|
||||||
|
err = memif_request_connection(conn);
|
||||||
|
if ((err < 0) && (lm->disconn_slaves == 1))
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -889,10 +911,77 @@ error:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
memif_request_connection(memif_conn_handle_t c)
|
||||||
|
{
|
||||||
|
libmemif_main_t *lm = &libmemif_main;
|
||||||
|
memif_connection_t *conn = (memif_connection_t *) c;
|
||||||
|
int err = MEMIF_ERR_SUCCESS;
|
||||||
|
int sockfd = -1;
|
||||||
|
struct sockaddr_un sun;
|
||||||
|
|
||||||
|
if (conn->args.is_master)
|
||||||
|
return MEMIF_ERR_INVAL_ARG;
|
||||||
|
if (conn->fd > 0)
|
||||||
|
return MEMIF_ERR_ALRCONN;
|
||||||
|
|
||||||
|
sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
|
||||||
|
if (sockfd < 0)
|
||||||
|
{
|
||||||
|
err = memif_syscall_error_handler (errno);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
sun.sun_family = AF_UNIX;
|
||||||
|
|
||||||
|
strncpy (sun.sun_path, (char *) conn->args.socket_filename,
|
||||||
|
sizeof (sun.sun_path) - 1);
|
||||||
|
|
||||||
|
if (connect (sockfd, (struct sockaddr *) &sun,
|
||||||
|
sizeof (struct sockaddr_un)) == 0)
|
||||||
|
{
|
||||||
|
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->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
|
||||||
|
{
|
||||||
|
strcpy ((char *) conn->remote_disconnect_string,
|
||||||
|
memif_strerror (memif_syscall_error_handler
|
||||||
|
(errno)));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (sockfd > 0)
|
||||||
|
close (sockfd);
|
||||||
|
sockfd = -1;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
memif_control_fd_handler (int fd, uint8_t events)
|
memif_control_fd_handler (int fd, uint8_t events)
|
||||||
{
|
{
|
||||||
int i, sockfd = -1, err = MEMIF_ERR_SUCCESS; /* 0 */
|
int i, err = MEMIF_ERR_SUCCESS; /* 0 */
|
||||||
uint16_t num;
|
uint16_t num;
|
||||||
memif_list_elt_t *e = NULL;
|
memif_list_elt_t *e = NULL;
|
||||||
memif_connection_t *conn;
|
memif_connection_t *conn;
|
||||||
@ -914,51 +1003,7 @@ memif_control_fd_handler (int fd, uint8_t events)
|
|||||||
conn = lm->control_list[i].data_struct;
|
conn = lm->control_list[i].data_struct;
|
||||||
if (conn->args.is_master)
|
if (conn->args.is_master)
|
||||||
continue;
|
continue;
|
||||||
|
memif_request_connection(conn);
|
||||||
struct sockaddr_un sun;
|
|
||||||
sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
|
|
||||||
if (sockfd < 0)
|
|
||||||
{
|
|
||||||
err = memif_syscall_error_handler (errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
sun.sun_family = AF_UNIX;
|
|
||||||
|
|
||||||
strncpy (sun.sun_path, (char *) conn->args.socket_filename,
|
|
||||||
sizeof (sun.sun_path) - 1);
|
|
||||||
|
|
||||||
if (connect (sockfd, (struct sockaddr *) &sun,
|
|
||||||
sizeof (struct sockaddr_un)) == 0)
|
|
||||||
{
|
|
||||||
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->disconn_slaves--;
|
|
||||||
if (lm->disconn_slaves == 0)
|
|
||||||
{
|
|
||||||
if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL)
|
|
||||||
< 0)
|
|
||||||
{
|
|
||||||
err = memif_syscall_error_handler (errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy ((char *) conn->remote_disconnect_string,
|
|
||||||
memif_strerror (memif_syscall_error_handler
|
|
||||||
(errno)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -993,15 +1038,15 @@ memif_control_fd_handler (int fd, uint8_t events)
|
|||||||
get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
|
get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
|
||||||
if (e != NULL)
|
if (e != NULL)
|
||||||
{
|
{
|
||||||
memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
|
err = memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
|
||||||
return MEMIF_ERR_SUCCESS;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
|
get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
|
||||||
if (e != NULL)
|
if (e != NULL)
|
||||||
{
|
{
|
||||||
memif_read_ready (fd);
|
err = memif_read_ready (fd);
|
||||||
return MEMIF_ERR_SUCCESS;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
|
get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
|
||||||
@ -1037,9 +1082,6 @@ memif_control_fd_handler (int fd, uint8_t events)
|
|||||||
return MEMIF_ERR_SUCCESS; /* 0 */
|
return MEMIF_ERR_SUCCESS; /* 0 */
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (sockfd > 0)
|
|
||||||
close (sockfd);
|
|
||||||
sockfd = -1;
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
|
|||||||
#define MEMIF_DEFAULT_RX_QUEUES 1
|
#define MEMIF_DEFAULT_RX_QUEUES 1
|
||||||
#define MEMIF_DEFAULT_TX_QUEUES 1
|
#define MEMIF_DEFAULT_TX_QUEUES 1
|
||||||
#define MEMIF_DEFAULT_BUFFER_SIZE 2048
|
#define MEMIF_DEFAULT_BUFFER_SIZE 2048
|
||||||
|
#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC 2
|
||||||
|
#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC 0
|
||||||
|
|
||||||
#define MEMIF_MAX_M2S_RING 255
|
#define MEMIF_MAX_M2S_RING 255
|
||||||
#define MEMIF_MAX_S2M_RING 255
|
#define MEMIF_MAX_S2M_RING 255
|
||||||
|
@ -681,7 +681,6 @@ memif_msg_receive (int ifd)
|
|||||||
|
|
||||||
DBG ("recvmsg fd %d", ifd);
|
DBG ("recvmsg fd %d", ifd);
|
||||||
size = recvmsg (ifd, &mh, 0);
|
size = recvmsg (ifd, &mh, 0);
|
||||||
DBG ("done");
|
|
||||||
if (size != sizeof (memif_msg_t))
|
if (size != sizeof (memif_msg_t))
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@ -903,8 +902,8 @@ int
|
|||||||
memif_read_ready (int fd)
|
memif_read_ready (int fd)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
DBG ("call recv");
|
|
||||||
err = memif_msg_receive (fd);
|
err = memif_msg_receive (fd);
|
||||||
DBG ("recv finished");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user