From 17d1aeda18046f2b7225075d121ed54605a5adb9 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 8 Jan 2021 09:59:17 +0530 Subject: dlt_client_main_loop running in an infinite loop restricts graceful exit of DLT Client code (#284) Issue: ------ dlt_client_main_loop currently uses an infinite loop ("while (1)"). This creates problems when a DLT client is running in a thread as part of a larger application. Graceful exit (for example: during object destruction) is not possible because a thread is running dlt_client_main_loop in the background. It is also not possible to exit the client, if we want it to fetch only a pre-decided number of messages. Solution: --------- Allow user to define a callback function to check whether the next message should be fetched. dlt-test-client.c has a new option to fetch a pre-decided number of messages, after which the client will exit. Signed-off-by: Sreeharsha Ramanavarapu --- include/dlt/dlt_client.h | 2 ++ src/lib/dlt_client.c | 11 ++++++++++- src/tests/dlt-test-client.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/include/dlt/dlt_client.h b/include/dlt/dlt_client.h index f649b83..77f0cee 100644 --- a/include/dlt/dlt_client.h +++ b/include/dlt/dlt_client.h @@ -75,6 +75,7 @@ # include "dlt_types.h" # include "dlt_common.h" +#include typedef enum { @@ -104,6 +105,7 @@ extern "C" { # endif void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data)); +void dlt_client_register_fetch_next_message_callback(bool (*registerd_callback)(void *data)); /** * Initialising dlt client structure with a specific port diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c index 0702f5f..b81d61b 100644 --- a/src/lib/dlt_client.c +++ b/src/lib/dlt_client.c @@ -97,12 +97,18 @@ #include "dlt_client_cfg.h" static int (*message_callback_function)(DltMessage *message, void *data) = NULL; +static bool (*fetch_next_message_callback_function)(void *data) = NULL; void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data)) { message_callback_function = registerd_callback; } +void dlt_client_register_fetch_next_message_callback(bool (*registerd_callback)(void *data)) +{ + fetch_next_message_callback_function = registerd_callback; +} + DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose) { if (verbose && (port != DLT_DAEMON_TCP_PORT)) @@ -397,7 +403,8 @@ DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose) if (dlt_message_init(&msg, verbose) == DLT_RETURN_ERROR) return DLT_RETURN_ERROR; - while (1) { + bool fetch_next_message = true; + while (fetch_next_message) { /* wait for data from socket or serial connection */ ret = dlt_receiver_receive(&(client->receiver)); @@ -440,6 +447,8 @@ DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose) dlt_message_free(&msg, verbose); return DLT_RETURN_ERROR; } + if (fetch_next_message_callback_function) + fetch_next_message = (*fetch_next_message_callback_function)(data); } if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR) diff --git a/src/tests/dlt-test-client.c b/src/tests/dlt-test-client.c index edac717..5273aa2 100644 --- a/src/tests/dlt-test-client.c +++ b/src/tests/dlt-test-client.c @@ -70,6 +70,8 @@ #include /* for atoi() */ #include /* for strcmp() */ #include /* for writev() */ +#include +#include #include "dlt_client.h" #include "dlt_protocol.h" @@ -84,6 +86,7 @@ static int g_testsFailed = 0; DltClient g_dltclient; /* Function prototypes */ int dlt_testclient_message_callback(DltMessage *message, void *data); +bool dlt_testclient_fetch_next_message_callback(void *data); typedef struct { @@ -114,6 +117,7 @@ typedef struct int tests_failed; int sock; + int max_messages; } DltTestclientData; /** @@ -140,6 +144,7 @@ void usage() printf(" -e ecuid Set ECU ID (Default: ECU1)\n"); printf(" -o filename Output messages in new DLT file\n"); printf(" -f filename Enable filtering of messages\n"); + printf(" -z max msgs Print z DLT messages\n"); } /** @@ -165,6 +170,7 @@ int main(int argc, char *argv[]) dltdata.ohandle = -1; dltdata.running_test = 0; + dltdata.max_messages = INT_MIN; for (i = 0; i < DLT_TESTCLIENT_NUM_TESTS; i++) { dltdata.test_counter_macro[i] = 0; @@ -179,7 +185,7 @@ int main(int argc, char *argv[]) /* Fetch command line arguments */ opterr = 0; - while ((c = getopt (argc, argv, "vashyxmf:o:e:b:")) != -1) + while ((c = getopt (argc, argv, "vashyxmf:o:e:b:z:")) != -1) switch (c) { case 'v': { @@ -236,6 +242,11 @@ int main(int argc, char *argv[]) dltdata.bvalue = atoi(optarg); break; } + case 'z': + { + dltdata.max_messages = atoi(optarg); + break; + } case '?': { if ((optopt == 'o') || (optopt == 'f') || (optopt == 't')) @@ -262,6 +273,9 @@ int main(int argc, char *argv[]) /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_testclient_message_callback); + /* Register callback to be called if next message needs to be fetched */ + dlt_client_register_fetch_next_message_callback(dlt_testclient_fetch_next_message_callback); + /* Setup DLT Client structure */ g_dltclient.mode = dltdata.yflag; @@ -354,6 +368,21 @@ int main(int argc, char *argv[]) return g_testsFailed == 0 ? 0 : 1; } +bool dlt_testclient_fetch_next_message_callback(void *data) +{ + if (data == 0) + return true; + + DltTestclientData *dltdata = (DltTestclientData *)data; + if (dltdata->max_messages > INT_MIN) + { + dltdata->max_messages--; + if (dltdata->max_messages <= 0) + return false; + } + return true; +} + int dlt_testclient_message_callback(DltMessage *message, void *data) { static char text[DLT_TESTCLIENT_TEXTBUFSIZE]; -- cgit v1.2.1