diff options
author | ManikandanC <Manikandan.Chockalingam@in.bosch.com> | 2017-10-06 11:37:31 +0530 |
---|---|---|
committer | Christoph Lipka <clipka@users.noreply.github.com> | 2018-11-30 12:17:59 +0100 |
commit | 73180fc762f015935950f697822710af3f5bd23d (patch) | |
tree | ffcd8407d8ab55d63544af33ade7efd120381728 /src/daemon | |
parent | 13803189600c724341148af34f33688497d71991 (diff) | |
download | DLT-daemon-73180fc762f015935950f697822710af3f5bd23d.tar.gz |
Use poll in the dlt-daemon for POSIX compliance
The poll system call is now used in the daemon to enable DLT use in
POSIX compliant systems. Also added introduced new unregister_app macro
to avoid missing of logs in startup buffer.
Signed-off-by: Frederic Berat <fberat@de.adit-jv.com>
Signed-off-by: ManikandanC <Manikandan.Chockalingam@in.bosch.com>
Signed-off-by: Saya Sugiura <ssugiura@jp.adit-jv.com>
Signed-off-by: S. Hameed <shameed@jp.adit-jv.com>
Diffstat (limited to 'src/daemon')
-rw-r--r-- | src/daemon/CMakeLists.txt | 19 | ||||
-rw-r--r-- | src/daemon/dlt-daemon.c | 20 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_connection.c | 6 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_connection_types.h | 4 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_event_handler.c | 254 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_event_handler.h | 2 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_event_handler_types.h | 8 |
7 files changed, 201 insertions, 112 deletions
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 2f5c27a..e9fb2ba 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -20,9 +20,22 @@ if(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) message( STATUS "Added ${systemd_SRCS} to dlt-daemon") endif(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) -set(dlt_daemon_SRCS dlt-daemon.c dlt_daemon_common.c dlt_daemon_connection.c dlt_daemon_event_handler.c ${CMAKE_SOURCE_DIR}/src/gateway/dlt_gateway.c dlt_daemon_socket.c dlt_daemon_unix_socket.c dlt_daemon_serial.c dlt_daemon_client.c dlt_daemon_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/lib/dlt_client.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_config_file_parser.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage_behavior.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_protocol.c) +set(dlt_daemon_SRCS dlt-daemon.c dlt_daemon_common.c dlt_daemon_connection.c dlt_daemon_event_handler.c ${CMAKE_SOURCE_DIR}/src/gateway/dlt_gateway.c dlt_daemon_socket.c dlt_daemon_unix_socket.c dlt_daemon_serial.c dlt_daemon_client.c dlt_daemon_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/lib/dlt_client.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_config_file_parser.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage_behavior.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_protocol.c) + +if(WITH_DLT_SHM_ENABLE) + set(dlt_daemon_SRCS ${dlt_daemon_SRCS} ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c) +endif() + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(RT_LIBRARY rt) + set(SOCKET_LIBRARY "") +else() + set(RT_LIBRARY "") + set(SOCKET_LIBRARY socket) +endif() + add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS}) -target_link_libraries(dlt-daemon rt ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dlt-daemon ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS dlt-daemon RUNTIME DESTINATION bin @@ -33,7 +46,7 @@ install(TARGETS dlt-daemon if (WITH_DLT_UNIT_TESTS) add_library(dlt_daemon ${dlt_daemon_SRCS}) - target_link_libraries(dlt_daemon rt ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(dlt_daemon ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS dlt_daemon RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 2cf8632..9956e3b 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -1049,7 +1049,7 @@ static int dlt_daemon_init_serial(DltDaemonLocal *daemon_local) return dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, - EPOLLIN, + POLLIN, DLT_CONNECTION_CLIENT_MSG_SERIAL); } @@ -1121,7 +1121,7 @@ static int dlt_daemon_init_fifo(DltDaemonLocal *daemon_local) return dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, - EPOLLIN, + POLLIN, DLT_CONNECTION_APP_MSG); } #endif @@ -1159,7 +1159,7 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, - EPOLLIN, + POLLIN, DLT_CONNECTION_APP_CONNECT)) { dlt_log(LOG_CRIT, "Could not initialize app socket.\n"); @@ -1186,7 +1186,7 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, - EPOLLIN, + POLLIN, DLT_CONNECTION_CLIENT_CONNECT)) { dlt_log(LOG_ERR,"Could not initialize main socket.\n"); @@ -1211,7 +1211,7 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, if (dlt_connection_create(daemon_local, &daemon_local->pEvent, fd, - EPOLLIN, + POLLIN, DLT_CONNECTION_CONTROL_CONNECT)) { dlt_log(LOG_ERR, "Could not initialize control socket.\n"); @@ -1630,7 +1630,7 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, - EPOLLIN, + POLLIN, DLT_CONNECTION_CLIENT_MSG_TCP)) { dlt_log(LOG_ERR, "Failed to register new client. \n"); @@ -1901,7 +1901,7 @@ int dlt_daemon_process_control_connect( if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, - EPOLLIN, + POLLIN, DLT_CONNECTION_CONTROL_MSG)) { dlt_log(LOG_ERR, "Failed to register new client. \n"); @@ -1956,7 +1956,7 @@ int dlt_daemon_process_app_connect( if (dlt_connection_create(daemon_local, &daemon_local->pEvent, in_sock, - EPOLLIN, + POLLIN, DLT_CONNECTION_APP_MSG)) { dlt_log(LOG_ERR, "Failed to register new application. \n"); @@ -2003,7 +2003,7 @@ int dlt_daemon_process_control_messages( /* FIXME: Why the hell do we need to close the socket * on control message reception ?? */ - //return 0; + return 0; } /* Process all received messages */ @@ -3422,7 +3422,7 @@ int create_timer_fd(DltDaemonLocal *daemon_local, return dlt_connection_create(daemon_local, &daemon_local->pEvent, local_fd, - EPOLLIN, + POLLIN, dlt_timer_conn_types[timer_id]); } diff --git a/src/daemon/dlt_daemon_connection.c b/src/daemon/dlt_daemon_connection.c index 8a3913a..619811d 100644 --- a/src/daemon/dlt_daemon_connection.c +++ b/src/daemon/dlt_daemon_connection.c @@ -34,7 +34,7 @@ #include <unistd.h> #include <sys/socket.h> -#include <sys/syslog.h> +#include <syslog.h> #include <sys/types.h> #include "dlt_daemon_connection_types.h" @@ -331,7 +331,7 @@ void dlt_connection_destroy(DltConnection *to_destroy) to_destroy->id = 0; close(to_destroy->receiver->fd); dlt_connection_destroy_receiver(to_destroy); - /* connection pointer might be in epoll queue and used even after destroying + /* connection pointer might be in poll queue and used even after destroying * it. To make sure it is not used anymore, connection type is invalidated */ to_destroy->type = DLT_CONNECTION_TYPE_MAX; free(to_destroy); @@ -370,7 +370,7 @@ int dlt_connection_create(DltDaemonLocal *daemon_local, /* No need for the same client to be registered twice * for the same event. * TODO: If another mask can be expected, - * we need it to update the epoll event here. + * we need it to update the poll event here. */ return 0; } diff --git a/src/daemon/dlt_daemon_connection_types.h b/src/daemon/dlt_daemon_connection_types.h index bd89998..68a0400 100644 --- a/src/daemon/dlt_daemon_connection_types.h +++ b/src/daemon/dlt_daemon_connection_types.h @@ -33,8 +33,8 @@ typedef enum { UNDEFINED, /* Undefined status */ - INACTIVE, /* Connection is inactive, excluded from epoll handling */ - ACTIVE, /* Connection is actively handled by epoll */ + INACTIVE, /* Connection is inactive, excluded from poll handling */ + ACTIVE, /* Connection is actively handled by poll */ DEACTIVATE,/* Request for deactivation of the connection */ ACTIVATE /* Request for activation of the connection */ } DltConnectionStatus; diff --git a/src/daemon/dlt_daemon_event_handler.c b/src/daemon/dlt_daemon_event_handler.c index 135130d..2410565 100644 --- a/src/daemon/dlt_daemon_event_handler.c +++ b/src/daemon/dlt_daemon_event_handler.c @@ -28,11 +28,12 @@ */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <errno.h> -#include <sys/epoll.h> -#include <sys/syslog.h> +#include <sys/poll.h> +#include <syslog.h> #include "dlt_common.h" @@ -45,15 +46,31 @@ #include "dlt_daemon_event_handler_types.h" /** - * \def DLT_EPOLL_TIMEOUT_MSEC - * The maximum amount of time to wait for an epoll event. + * \def DLT_EV_TIMEOUT_MSEC + * The maximum amount of time to wait for a poll event. * Set to 1 second to avoid unnecessary wake ups. */ -#define DLT_EPOLL_TIMEOUT_MSEC 1000 +#define DLT_EV_TIMEOUT_MSEC 1000 +#define DLT_EV_BASE_FD 16 + +#define DLT_EV_MASK_REJECTED (POLLERR | POLLNVAL) + +/** @brief Initialize a pollfd structure + * + * That ensures that no event will be mis-watched. + * + * @param pfd: The element to initialize + */ +static void init_poll_fd(struct pollfd *pfd) +{ + pfd->fd = -1; + pfd->events = 0; + pfd->revents = 0; +} /** @brief Prepare the event handler * - * This will create the epoll file descriptor. + * This will create the base poll file descriptor list. * * @param ev The event handler to prepare. * @@ -61,21 +78,112 @@ */ int dlt_daemon_prepare_event_handling(DltEventHandler *ev) { + int i = 0; + if (ev == NULL) { return DLT_RETURN_ERROR; } - ev->epfd = epoll_create(DLT_EPOLL_MAX_EVENTS); - if (ev->epfd < 0) + ev->pfd = calloc(DLT_EV_BASE_FD, sizeof(struct pollfd)); + + if (ev->pfd == NULL) { - dlt_log(LOG_CRIT, "Creation of epoll instance failed!\n"); + dlt_log(LOG_CRIT, "Creation of poll instance failed!\n"); return -1; } + for (i = 0; i < DLT_EV_BASE_FD; i++) + { + init_poll_fd(&ev->pfd[i]); + } + + ev->nfds = 0; + ev->max_nfds = DLT_EV_BASE_FD; + return 0; } +/** @brief Enable a file descriptor to be watched + * + * Adds a file descriptor to the descriptor list. If the list is to small, + * increase its size. + * + * @param ev: The event handler structure, containing the list + * @param fd: The file descriptor to add + * @param mask: The mask of event to be watched + */ +static void dlt_event_handler_enable_fd(DltEventHandler *ev, int fd, int mask) +{ + if (ev->max_nfds <= ev->nfds) + { + int i = ev->nfds; + int max = 2 * ev->max_nfds; + struct pollfd *tmp = realloc(ev->pfd, max * sizeof(*ev->pfd)); + + if (!tmp) + { + dlt_log(LOG_CRIT, + "Unable to register new fd for the event handler.\n"); + return; + } + + ev->pfd = tmp; + ev->max_nfds = max; + + for (; i < max; i++) + { + init_poll_fd(&ev->pfd[i]); + } + } + + ev->pfd[ev->nfds].fd = fd; + ev->pfd[ev->nfds].events = mask; + ev->nfds++; +} + +/** @brief Disable a file descriptor for watching + * + * The file descriptor is removed from the descriptor list, the list is + * compressed during the process. + * + * @param ev: The event handler structure containing the list + * @param fd: The file descriptor to be removed + */ +static void dlt_event_handler_disable_fd(DltEventHandler *ev, int fd) +{ + unsigned int i = 0; + unsigned int j = 0; + unsigned int nfds = ev->nfds; + + for (; i < nfds; i++, j++) + { + if (ev->pfd[i].fd == fd) + { + init_poll_fd(&ev->pfd[i]); + j++; + ev->nfds--; + } + + if (i == j) + { + continue; + } + + /* Compressing the table */ + if (i < ev->nfds) + { + ev->pfd[i].fd = ev->pfd[j].fd; + ev->pfd[i].events = ev->pfd[j].events; + ev->pfd[i].revents = ev->pfd[j].revents; + } + else + { + init_poll_fd(&ev->pfd[i]); + } + } +} + /** @brief Catch and process incoming events. * * This function waits for events on all connections. Once an event raise, @@ -92,48 +200,49 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent, DltDaemon *daemon, DltDaemonLocal *daemon_local) { + int ret = 0; + unsigned int i = 0; + char str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; + int (*callback)(DltDaemon *, DltDaemonLocal *, DltReceiver *, int) = NULL; + if ((pEvent == NULL) || (daemon == NULL) || (daemon_local == NULL)) { return DLT_RETURN_ERROR; } - int nfds = 0; - int i = 0; - char str[DLT_DAEMON_TEXTBUFSIZE]; - int (*callback)(DltDaemon *, DltDaemonLocal *, DltReceiver *, int) = NULL; - /*CM Change begin*/ - nfds = epoll_wait(pEvent->epfd, - pEvent->events, - DLT_EPOLL_MAX_EVENTS, - DLT_EPOLL_TIMEOUT_MSEC); + ret = poll(pEvent->pfd, pEvent->nfds, DLT_EV_TIMEOUT_MSEC); - if (nfds < 0) + if (ret <= 0) { /* We are not interested in EINTR has it comes * either from timeout or signal. */ - if (errno != EINTR) + if (errno == EINTR) { - snprintf(str, - DLT_DAEMON_TEXTBUFSIZE, - "epoll_wait() failed: %s\n", - strerror(errno)); - dlt_log(LOG_CRIT, str); - return -1; + ret = 0; + } + + if (ret < 0) + { + dlt_vlog(LOG_CRIT, "poll() failed: %s\n", strerror(errno)); } - return 0; + return ret; } - for (i = 0 ; i < nfds ; i++) + for (i = 0 ; i < pEvent->nfds ; i++) { - struct epoll_event *ev = &pEvent->events[i]; - DltConnectionId id = (DltConnectionId)ev->data.ptr; - DltConnection *con = dlt_event_handler_find_connection_by_id(pEvent, - id); int fd = 0; + DltConnection *con = NULL; DltConnectionType type = DLT_CONNECTION_TYPE_MAX; + if (pEvent->pfd[i].revents == 0) + { + continue; + } + + con = dlt_event_handler_find_connection(pEvent, pEvent->pfd[i].fd); + if (con && con->receiver) { type = con->type; @@ -141,17 +250,15 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent, } else /* connection might have been destroyed in the meanwhile */ { + dlt_event_handler_disable_fd(pEvent, pEvent->pfd[i].fd); continue; } - /* First of all handle epoll error events - * We only expect EPOLLIN or EPOLLOUT - */ - if ((ev->events != EPOLLIN) && (ev->events != EPOLLOUT)) + /* First of all handle error events */ + if (pEvent->pfd[i].revents & DLT_EV_MASK_REJECTED) { - /* epoll reports an error, we need to clean-up the concerned event + /* An error occurred, we need to clean-up the concerned event */ - if (type == DLT_CONNECTION_CLIENT_MSG_TCP) { /* To transition to BUFFER state if this is final TCP client connection, @@ -224,31 +331,6 @@ DltConnection *dlt_event_handler_find_connection(DltEventHandler *ev, return temp; } -/** @brief Find connection with a specific \a id in the connection list. - * - * There can be only one event per \a fd. We can then find a specific connection - * based on this \a fd. That allows to check if a specific \a fd has already been - * registered. - * - * @param ev The event handler structure where the list of connection is. - * @param id The identifier of the connection to be found. - * - * @return The found connection pointer, NULL otherwise. - */ -DltConnection *dlt_event_handler_find_connection_by_id(DltEventHandler *ev, - DltConnectionId id) -{ - - DltConnection *temp = ev->connections; - - while ((temp != NULL) && (temp->id != id)) - { - temp = temp->next; - } - - return temp; -} - /** @brief Remove a connection from the list and destroy it. * * This function will first look for the connection in the event handler list, @@ -306,6 +388,8 @@ STATIC int dlt_daemon_remove_connection(DltEventHandler *ev, */ void dlt_event_handler_cleanup_connections(DltEventHandler *ev) { + unsigned int i = 0; + if (ev == NULL) { /* Nothing to do. */ @@ -317,6 +401,13 @@ void dlt_event_handler_cleanup_connections(DltEventHandler *ev) /* We don really care on failure */ (void)dlt_daemon_remove_connection(ev, ev->connections); } + + for (i = 0; i < ev->nfds; i++) + { + init_poll_fd(&ev->pfd[i]); + } + + free(ev->pfd); } /** @brief Add a new connection to the list. @@ -381,14 +472,7 @@ int dlt_connection_check_activate(DltEventHandler *evhdl, con->type); dlt_log(LOG_INFO, local_str); - if (epoll_ctl(evhdl->epfd, - EPOLL_CTL_DEL, - con->receiver->fd, - NULL) == -1) - { - dlt_log(LOG_ERR, "epoll_ctl() in deactivate failed!\n"); - return -1; - } + dlt_event_handler_disable_fd(evhdl, con->receiver->fd); con->status = INACTIVE; } @@ -396,25 +480,16 @@ int dlt_connection_check_activate(DltEventHandler *evhdl, case INACTIVE: if (activation_type == ACTIVATE) { - struct epoll_event ev; /* Content will be copied by the kernel */ - ev.events = con->ev_mask; - ev.data.ptr = (void *)con->id; - snprintf(local_str, DLT_DAEMON_TEXTBUFSIZE, "Activate connection type: %d\n", con->type); dlt_log(LOG_INFO, local_str); + dlt_event_handler_enable_fd(evhdl, + con->receiver->fd, + con->ev_mask); - if (epoll_ctl(evhdl->epfd, - EPOLL_CTL_ADD, - con->receiver->fd, - &ev) == -1) - { - dlt_log(LOG_ERR, "epoll_ctl() in activate failed!\n"); - return -1; - } con->status = ACTIVE; } break; @@ -447,11 +522,12 @@ int dlt_connection_check_activate(DltEventHandler *evhdl, * @return 0 on success, -1 otherwise. */ int dlt_event_handler_register_connection(DltEventHandler *evhdl, - DltDaemonLocal *daemon_local, - DltConnection *connection, - int mask) + DltDaemonLocal *daemon_local, + DltConnection *connection, + int mask) { - if (!evhdl || !connection || !connection->receiver) { + if (!evhdl || !connection || !connection->receiver) + { dlt_log(LOG_ERR, "Wrong parameters when registering connection.\n"); return -1; } @@ -490,8 +566,8 @@ int dlt_event_handler_register_connection(DltEventHandler *evhdl, * @return 0 on success, -1 otherwise. */ int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, - DltDaemonLocal *daemon_local, - int fd) + DltDaemonLocal *daemon_local, + int fd) { if (evhdl == NULL || daemon_local == NULL) { diff --git a/src/daemon/dlt_daemon_event_handler.h b/src/daemon/dlt_daemon_event_handler.h index dc91b89..280bfd7 100644 --- a/src/daemon/dlt_daemon_event_handler.h +++ b/src/daemon/dlt_daemon_event_handler.h @@ -27,7 +27,7 @@ * \file dlt_daemon_event_handler.h */ -#include <sys/epoll.h> +#include <sys/poll.h> #include "dlt_daemon_connection_types.h" #include "dlt_daemon_event_handler_types.h" diff --git a/src/daemon/dlt_daemon_event_handler_types.h b/src/daemon/dlt_daemon_event_handler_types.h index a2945b4..99a1217 100644 --- a/src/daemon/dlt_daemon_event_handler_types.h +++ b/src/daemon/dlt_daemon_event_handler_types.h @@ -27,7 +27,7 @@ * \file dlt_daemon_event_handler_types.h */ -#include <sys/epoll.h> +#include <sys/poll.h> #include "dlt_daemon_connection_types.h" @@ -50,10 +50,10 @@ typedef enum { DLT_TIMER_UNKNOWN } DltTimers; -#define DLT_EPOLL_MAX_EVENTS 10 typedef struct { - int epfd; - struct epoll_event events[DLT_EPOLL_MAX_EVENTS]; + struct pollfd *pfd; + nfds_t nfds; + nfds_t max_nfds; DltConnection *connections; } DltEventHandler; |