summaryrefslogtreecommitdiff
path: root/src/lib/dlt_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dlt_user.c')
-rw-r--r--src/lib/dlt_user.c311
1 files changed, 198 insertions, 113 deletions
diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c
index 99df11b..0397e48 100644
--- a/src/lib/dlt_user.c
+++ b/src/lib/dlt_user.c
@@ -85,14 +85,22 @@
int *p = NULL; \
*p = 0; \
} \
- } while (0)
+ } while (false)
#else /* DLT_FATAL_LOG_RESET_ENABLE */
# define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL)
#endif /* DLT_FATAL_LOG_RESET_ENABLE */
+enum InitState {
+ INIT_UNITIALIZED,
+ INIT_IN_PROGRESS,
+ INIT_DONE
+};
+
static DltUser dlt_user;
-static atomic_bool dlt_user_initialised = false;
-static int dlt_user_freeing = 0;
+static _Atomic enum InitState dlt_user_init_state = INIT_UNITIALIZED;
+#define DLT_USER_INITALIZED (dlt_user_init_state == INIT_DONE)
+
+static _Atomic int dlt_user_freeing = 0;
static bool dlt_user_file_reach_max = false;
#ifdef DLT_LIB_USE_FIFO_IPC
@@ -103,6 +111,10 @@ static char dlt_daemon_fifo[DLT_PATH_MAX];
static sem_t dlt_mutex;
static pthread_t dlt_housekeeperthread_handle;
+/* Sync housekeeper thread start */
+pthread_mutex_t dlt_housekeeper_running_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t dlt_housekeeper_running_cond;
+
/* calling dlt_user_atexit_handler() second time fails with error message */
static int atexit_registered = 0;
@@ -209,7 +221,7 @@ static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *
#endif
static DltReturnValue dlt_user_log_write_string_utils_attr(DltContextData *log, const char *text, const enum StringType type, const char *name, bool with_var_info);
-static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, uint16_t length, const enum StringType type, const char *name, bool with_var_info);
+static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, size_t length, const enum StringType type, const char *name, bool with_var_info);
static DltReturnValue dlt_unregister_app_util(bool force_sending_messages);
@@ -308,7 +320,7 @@ static DltReturnValue dlt_initialize_socket_connection(void)
sockfd,
DLT_RECEIVE_SOCKET,
DLT_USER_RCVBUF_MAX_SIZE) == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
close(sockfd);
DLT_SEM_FREE();
return DLT_RETURN_ERROR;
@@ -363,7 +375,7 @@ static DltReturnValue dlt_initialize_vsock_connection()
sockfd,
DLT_RECEIVE_SOCKET,
DLT_USER_RCVBUF_MAX_SIZE) == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
close(sockfd);
DLT_SEM_FREE();
return DLT_RETURN_ERROR;
@@ -445,35 +457,37 @@ static DltReturnValue dlt_initialize_fifo_connection(void)
DltReturnValue dlt_init(void)
{
- /* Compare 'dlt_user_initialised' to false. If equal, 'dlt_user_initialised' will be set to true.
- Calls retruns true, if 'dlt_user_initialised' was false.
- That way it's no problem, if two threads enter this function, because only the very first one will
- pass fully. The other one will immediately return, because when it executes the atomic function
- 'dlt_user_initialised' will be for sure already set to true.
- */
- bool expected = false;
- if (!(atomic_compare_exchange_strong(&dlt_user_initialised, &expected, true)))
+ /* process is exiting. Do not allocate new resources. */
+ if (dlt_user_freeing != 0) {
+ dlt_vlog(LOG_INFO, "%s logging disabled, process is exiting\n", __func__);
+ /* return negative value, to stop the current log */
+ return DLT_RETURN_LOGGING_DISABLED;
+ }
+
+ /* Compare dlt_user_init_state to INIT_UNITIALIZED. If equal it will be set to INIT_IN_PROGRESS.
+ * Call returns DLT_RETURN_OK init state != INIT_UNITIALIZED
+ * That way it's no problem, if two threads enter this function, because only the very first one will
+ * pass fully. The other one will immediately return, because when it executes the atomic function
+ * dlt_user_init_state won't be INIT_UNITIALIZED anymore.
+ * This is not handled via a simple boolean to prevent issues with shutting down while the init is still running.
+ * Furthermore, this makes sure we enter some function only when dlt_init is fully done.
+ * */
+ enum InitState expectedInitState = INIT_UNITIALIZED;
+ if (!(atomic_compare_exchange_strong(&dlt_user_init_state, &expectedInitState, INIT_IN_PROGRESS))) {
return DLT_RETURN_OK;
+ }
/* check environment variables */
dlt_check_envvar();
/* Check logging mode and internal log file is opened or not*/
- if(logging_mode == DLT_LOG_TO_FILE && logging_handle == NULL)
- {
+ if (logging_mode == DLT_LOG_TO_FILE && logging_handle == NULL) {
dlt_log_init(logging_mode);
}
- /* process is exiting. Do not allocate new resources. */
- if (dlt_user_freeing != 0) {
- dlt_vlog(LOG_INFO, "%s logging disabled, process is exiting", __func__);
- /* return negative value, to stop the current log */
- return DLT_RETURN_LOGGING_DISABLED;
- }
-
/* Initialize common part of dlt_init()/dlt_init_file() */
if (dlt_init_common() == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
return DLT_RETURN_ERROR;
}
@@ -515,7 +529,7 @@ DltReturnValue dlt_init(void)
dlt_user.dlt_user_handle,
DLT_RECEIVE_FD,
DLT_USER_RCVBUF_MAX_SIZE) == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
return DLT_RETURN_ERROR;
}
@@ -530,13 +544,18 @@ DltReturnValue dlt_init(void)
#endif
if (dlt_start_threads() < 0) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
return DLT_RETURN_ERROR;
}
/* prepare for fork() call */
pthread_atfork(NULL, NULL, &dlt_fork_child_fork_handler);
+ expectedInitState = INIT_IN_PROGRESS;
+ if (!(atomic_compare_exchange_strong(&dlt_user_init_state, &expectedInitState, INIT_DONE))) {
+ return DLT_RETURN_ERROR;
+ }
+
return DLT_RETURN_OK;
}
@@ -557,19 +576,21 @@ DltReturnValue dlt_init_file(const char *name)
if (!name)
return DLT_RETURN_WRONG_PARAMETER;
- /* Compare 'dlt_user_initialised' to false. If equal, 'dlt_user_initialised' will be set to true.
- Calls retruns true, if 'dlt_user_initialised' was false.
- That way it's no problem, if two threads enter this function, because only the very first one will
- pass fully. The other one will immediately return, because when it executes the atomic function
- 'dlt_user_initialised' will be for sure already set to true.
- */
- bool expected = false;
- if (!(atomic_compare_exchange_strong(&dlt_user_initialised, &expected, true)))
+ /* Compare dlt_user_init_state to INIT_UNITIALIZED. If equal it will be set to INIT_IN_PROGRESS.
+ * Call returns DLT_RETURN_OK init state != INIT_UNITIALIZED
+ * That way it's no problem, if two threads enter this function, because only the very first one will
+ * pass fully. The other one will immediately return, because when it executes the atomic function
+ * dlt_user_init_state won't be INIT_UNITIALIZED anymore.
+ * This is not handled via a simple boolean to prevent issues with shutting down while the init is still running.
+ * Furthermore, this makes sure we enter some function only when dlt_init is fully done.
+ * */
+ enum InitState expectedInitState = INIT_UNITIALIZED;
+ if (!(atomic_compare_exchange_strong(&dlt_user_init_state, &expectedInitState, INIT_IN_PROGRESS)))
return DLT_RETURN_OK;
/* Initialize common part of dlt_init()/dlt_init_file() */
if (dlt_init_common() == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ expectedInitState = INIT_UNITIALIZED;
return DLT_RETURN_ERROR;
}
@@ -699,7 +720,7 @@ DltReturnValue dlt_init_common(void)
/* Binary semaphore for threads */
if (sem_init(&dlt_mutex, 0, 1) == -1) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
return DLT_RETURN_ERROR;
}
@@ -846,7 +867,7 @@ DltReturnValue dlt_init_common(void)
(dlt_user.log_buf_len + header_size));
if (dlt_user.resend_buffer == NULL) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
DLT_SEM_FREE();
dlt_vlog(LOG_ERR, "cannot allocate memory for resend buffer\n");
return DLT_RETURN_ERROR;
@@ -863,7 +884,7 @@ DltReturnValue dlt_init_common(void)
buffer_min,
buffer_max,
buffer_step) == DLT_RETURN_ERROR) {
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
DLT_SEM_FREE();
return DLT_RETURN_ERROR;
}
@@ -892,8 +913,8 @@ void dlt_user_atexit_handler(void)
if (g_dlt_is_child)
return;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
/* close file */
dlt_log_free();
return;
@@ -981,26 +1002,26 @@ DltReturnValue dlt_free(void)
{
uint32_t i;
int ret = 0;
+ int expected = 0;
#ifdef DLT_LIB_USE_FIFO_IPC
char filename[DLT_PATH_MAX];
#endif
- if (dlt_user_freeing != 0)
+ /* library is freeing its resources. Avoid to allocate it in dlt_init() */
+ if (!(atomic_compare_exchange_strong(&dlt_user_freeing, &expected, 1))) {
/* resources are already being freed. Do nothing and return. */
return DLT_RETURN_ERROR;
+ }
- /* library is freeing its resources. Avoid to allocate it in dlt_init() */
- dlt_user_freeing = 1;
-
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
dlt_user_freeing = 0;
return DLT_RETURN_ERROR;
}
- dlt_user_initialised = false;
-
dlt_stop_threads();
+ dlt_user_init_state = INIT_UNITIALIZED;
+
#ifdef DLT_LIB_USE_FIFO_IPC
if (dlt_user.dlt_user_handle != DLT_FD_INIT) {
@@ -1184,7 +1205,7 @@ DltReturnValue dlt_register_app(const char *apid, const char *description)
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1263,7 +1284,7 @@ DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, c
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1512,7 +1533,7 @@ DltReturnValue dlt_register_context_llccb(DltContext *handle,
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1537,8 +1558,8 @@ DltReturnValue dlt_unregister_app_util(bool force_sending_messages)
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -1578,8 +1599,8 @@ DltReturnValue dlt_unregister_app_flush_buffered_logs(void)
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __func__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -1669,7 +1690,7 @@ DltReturnValue dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTrac
return DLT_RETURN_WRONG_PARAMETER;
}
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1719,7 +1740,7 @@ DltReturnValue dlt_set_log_mode(DltUserLogMode mode)
return DLT_RETURN_WRONG_PARAMETER;
}
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < 0) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -1735,7 +1756,7 @@ int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds)
if (g_dlt_is_child)
return DLT_RETURN_ERROR;
- if (dlt_user_initialised == 0)
+ if (DLT_USER_INITALIZED == 0)
if (dlt_init() < 0)
return -1;
@@ -1813,27 +1834,34 @@ DltReturnValue dlt_user_log_write_start_internal(DltContext *handle,
ret = dlt_user_log_write_start_init(handle, log, loglevel, is_verbose);
if (ret == DLT_RETURN_TRUE) {
/* initialize values */
- if (log->buffer == NULL) {
+ if ((NULL != log->buffer))
+ {
+ free(log->buffer);
+ log->buffer = NULL;
+ }
+ else
+ {
log->buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len);
-
- if (log->buffer == NULL) {
- dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n");
- return DLT_RETURN_ERROR;
- }
}
- /* In non-verbose mode, insert message id */
- if (!is_verbose_mode(dlt_user.verbose_mode, log)) {
- if ((sizeof(uint32_t)) > dlt_user.log_buf_len) {
- return DLT_RETURN_USER_BUFFER_FULL;
- }
+ if (log->buffer == NULL) {
+ dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n");
+ return DLT_RETURN_ERROR;
+ }
+ else
+ {
+ /* In non-verbose mode, insert message id */
+ if (!is_verbose_mode(dlt_user.verbose_mode, log)) {
+ if ((sizeof(uint32_t)) > dlt_user.log_buf_len)
+ return DLT_RETURN_USER_BUFFER_FULL;
- /* Write message id */
- memcpy(log->buffer, &(messageid), sizeof(uint32_t));
- log->size = sizeof(uint32_t);
+ /* Write message id */
+ memcpy(log->buffer, &(messageid), sizeof(uint32_t));
+ log->size = sizeof(uint32_t);
- /* as the message id is part of each message in non-verbose mode,
- * it doesn't increment the argument counter in extended header (if used) */
+ /* as the message id is part of each message in non-verbose mode,
+ * it doesn't increment the argument counter in extended header (if used) */
+ }
}
}
@@ -1874,7 +1902,7 @@ DltReturnValue dlt_user_log_write_start_w_given_buffer(DltContext *handle,
return ret;
}
-
+
DltReturnValue dlt_user_log_write_finish(DltContextData *log)
{
int ret = DLT_RETURN_ERROR;
@@ -1913,8 +1941,8 @@ static DltReturnValue dlt_user_log_write_raw_internal(DltContextData *log, const
return DLT_RETURN_WRONG_PARAMETER;
}
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2007,8 +2035,8 @@ static DltReturnValue dlt_user_log_write_generic_attr(DltContextData *log, const
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2086,8 +2114,8 @@ static DltReturnValue dlt_user_log_write_generic_formatted(DltContextData *log,
return DLT_RETURN_WRONG_PARAMETER;
}
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2162,8 +2190,8 @@ DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data)
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2227,7 +2255,7 @@ DltReturnValue dlt_user_log_write_uint_attr(DltContextData *log, unsigned int da
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2320,7 +2348,7 @@ DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data)
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
dlt_vlog(LOG_WARNING, "%s user_initialised false\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2348,8 +2376,8 @@ DltReturnValue dlt_user_log_write_int(DltContextData *log, int data)
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2413,7 +2441,7 @@ DltReturnValue dlt_user_log_write_int_attr(DltContextData *log, int data, const
if (log == NULL)
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -2578,19 +2606,19 @@ DltReturnValue dlt_user_log_write_sized_constant_utf8_string_attr(DltContextData
return is_verbose_mode(dlt_user.verbose_mode, log) ? dlt_user_log_write_sized_utf8_string_attr(log, text, length, name) : DLT_RETURN_OK;
}
-static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, uint16_t length, const enum StringType type, const char *name, bool with_var_info)
+static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, size_t length, const enum StringType type, const char *name, bool with_var_info)
{
if ((log == NULL) || (text == NULL))
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
const uint16_t name_size = (name != NULL) ? strlen(name)+1 : 0;
- uint16_t arg_size = (uint16_t) (length + 1);
+ size_t arg_size = (size_t) (length + 1);
size_t new_log_size = log->size + arg_size + sizeof(uint16_t);
@@ -2615,13 +2643,13 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData
ret = DLT_RETURN_USER_BUFFER_FULL;
/* Re-calculate arg_size */
- arg_size = (uint16_t) (dlt_user.log_buf_len - log->size - sizeof(uint16_t));
+ arg_size = (size_t) (dlt_user.log_buf_len - log->size - sizeof(uint16_t));
size_t min_payload_str_truncate_msg = log->size + str_truncate_message_length + sizeof(uint16_t);
if (is_verbose_mode(dlt_user.verbose_mode, log)) {
min_payload_str_truncate_msg += sizeof(uint32_t);
- arg_size -= (uint16_t) sizeof(uint32_t);
+ arg_size -= (size_t) sizeof(uint32_t);
if (with_var_info) {
min_payload_str_truncate_msg += sizeof(uint16_t) + name_size;
arg_size -= sizeof(uint16_t) + name_size;
@@ -2659,7 +2687,7 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData
}
max_payload_str_msg -= reduce_size;
- arg_size -= (uint16_t) reduce_size;
+ arg_size -= (size_t) reduce_size;
}
}
@@ -2738,7 +2766,7 @@ static DltReturnValue dlt_user_log_write_string_utils_attr(DltContextData *log,
if ((log == NULL) || (text == NULL))
return DLT_RETURN_WRONG_PARAMETER;
- uint16_t length = (uint16_t) strlen(text);
+ size_t length = strlen(text);
return dlt_user_log_write_sized_string_utils_attr(log, text, length, type, name, with_var_info);
}
@@ -3248,7 +3276,7 @@ DltReturnValue dlt_user_trace_network_segmented(DltContext *handle,
return DLT_RETURN_ERROR;
/* Send as normal trace if possible */
- if (header_len + payload_len + (uint16_t) sizeof(uint16_t) < dlt_user.log_buf_len)
+ if (header_len + payload_len + sizeof(uint16_t) < dlt_user.log_buf_len)
return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
/* Allocate Memory */
@@ -3378,7 +3406,7 @@ DltReturnValue dlt_user_trace_network_truncated(DltContext *handle,
header_len = 0;
/* If truncation is allowed, check if we must do it */
- if ((allow_truncate > 0) && ((header_len + payload_len + (uint16_t) sizeof(uint16_t)) > dlt_user.log_buf_len)) {
+ if ((allow_truncate > 0) && ((header_len + payload_len + sizeof(uint16_t)) > dlt_user.log_buf_len)) {
/* Identify as truncated */
if (dlt_user_log_write_string(&log, DLT_TRACE_NW_TRUNCATED) < DLT_RETURN_OK) {
dlt_user_free_buffer(&(log.buffer));
@@ -3570,7 +3598,7 @@ DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *d
DltReturnValue dlt_log_marker()
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3582,7 +3610,7 @@ DltReturnValue dlt_log_marker()
DltReturnValue dlt_verbose_mode(void)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3597,7 +3625,7 @@ DltReturnValue dlt_verbose_mode(void)
DltReturnValue dlt_nonverbose_mode(void)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3612,7 +3640,7 @@ DltReturnValue dlt_nonverbose_mode(void)
DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extended_header_for_non_verbose)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3627,7 +3655,7 @@ DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extended_heade
DltReturnValue dlt_with_session_id(int8_t with_session_id)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3642,7 +3670,7 @@ DltReturnValue dlt_with_session_id(int8_t with_session_id)
DltReturnValue dlt_with_timestamp(int8_t with_timestamp)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3657,7 +3685,7 @@ DltReturnValue dlt_with_timestamp(int8_t with_timestamp)
DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3672,7 +3700,7 @@ DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id)
DltReturnValue dlt_enable_local_print(void)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3686,7 +3714,7 @@ DltReturnValue dlt_enable_local_print(void)
DltReturnValue dlt_disable_local_print(void)
{
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
if (dlt_init() < DLT_RETURN_OK) {
dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
return DLT_RETURN_ERROR;
@@ -3712,10 +3740,12 @@ static void dlt_user_cleanup_handler(void *arg)
DLT_SEM_FREE();
}
-void dlt_user_housekeeperthread_function(__attribute__((unused)) void *ptr)
+void dlt_user_housekeeperthread_function(void *ptr)
{
struct timespec ts;
bool in_loop = true;
+ int signal_status = 0;
+ atomic_bool* dlt_housekeeper_running = (atomic_bool*)ptr;
#ifdef __ANDROID_API__
sigset_t set;
@@ -3743,6 +3773,13 @@ void dlt_user_housekeeperthread_function(__attribute__((unused)) void *ptr)
pthread_cleanup_push(dlt_user_cleanup_handler, NULL);
+ // signal dlt thread to be running
+ *dlt_housekeeper_running = true;
+ signal_status = pthread_cond_signal(&dlt_housekeeper_running_cond);
+ if (signal_status != 0) {
+ dlt_log(LOG_CRIT, "Housekeeper thread failed to signal running state\n");
+ }
+
while (in_loop) {
/* Check for new messages from DLT daemon */
if (!dlt_user.disable_injection_msg)
@@ -3787,7 +3824,7 @@ DltReturnValue dlt_user_log_init(DltContext *handle, DltContextData *log)
if ((handle == NULL) || (log == NULL))
return DLT_RETURN_WRONG_PARAMETER;
- if (!dlt_user_initialised) {
+ if (!DLT_USER_INITALIZED) {
ret = dlt_init();
if (ret < DLT_RETURN_OK) {
@@ -3811,8 +3848,8 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
DltReturnValue ret = DLT_RETURN_OK;
- if (!dlt_user_initialised) {
- dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __FUNCTION__);
+ if (!DLT_USER_INITALIZED) {
+ dlt_vlog(LOG_WARNING, "%s dlt_user_init_state != INIT_DONE\n", __FUNCTION__);
return DLT_RETURN_ERROR;
}
@@ -4920,15 +4957,63 @@ void dlt_user_test_corrupt_message_size(int enable, int16_t size)
int dlt_start_threads()
{
- /* Start housekeeper thread */
+ struct timespec time_to_wait;
+ struct timespec now;
+ int signal_status;
+ atomic_bool dlt_housekeeper_running = false;
+
+ /*
+ * Configure the condition varibale to use CLOCK_MONOTONIC.
+ * This makes sure we're protected against changes in the system clock
+ */
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ pthread_cond_init(&dlt_housekeeper_running_cond, &attr);
+
if (pthread_create(&(dlt_housekeeperthread_handle),
0,
(void *)&dlt_user_housekeeperthread_function,
- 0) != 0) {
+ &dlt_housekeeper_running) != 0) {
dlt_log(LOG_CRIT, "Can't create housekeeper thread!\n");
return -1;
}
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ /* wait at most 10s */
+ time_to_wait.tv_sec = now.tv_sec + 10;
+ time_to_wait.tv_nsec = 0;
+
+ /*
+ * wait until the house keeper is up and running
+ * Even though the condition variable and the while are
+ * using the same time out the while loop is not a no op.
+ * This is due to the fact that the pthread_cond_timedwait
+ * can be woken before time is up and dlt_housekeeper_running is not true yet.
+ * (spurious wakeup)
+ * To protect against this, a while loop with a timeout is added
+ * */
+ while (!dlt_housekeeper_running
+ && now.tv_sec <= time_to_wait.tv_sec) {
+ signal_status = pthread_cond_timedwait(
+ &dlt_housekeeper_running_cond,
+ &dlt_housekeeper_running_mutex,
+ &time_to_wait);
+
+ /* otherwise it might be a spurious wakeup, try again until the time is over */
+ if (signal_status == 0) {
+ break;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ }
+
+ if (signal_status != 0 && !dlt_housekeeper_running) {
+ dlt_log(LOG_CRIT, "Failed to wait for house keeper thread!\n");
+ dlt_stop_threads();
+ return -1;
+ }
+
#ifdef DLT_NETWORK_TRACE_ENABLE
/* Start the segmented thread */
if (pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
@@ -5015,7 +5100,7 @@ void dlt_stop_threads()
static void dlt_fork_child_fork_handler()
{
g_dlt_is_child = 1;
- dlt_user_initialised = false;
+ dlt_user_init_state = INIT_UNITIALIZED;
dlt_user.dlt_log_handle = -1;
}