Message ID | 20221214002129.2105777-1-luiz.dentz@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [BlueZ,1/3] client/player: Make transport.send non-blocking | expand |
This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=704331 ---Test result--- Test Summary: CheckPatch FAIL 1.72 seconds GitLint PASS 0.73 seconds BuildEll PASS 33.49 seconds BluezMake FAIL 24.37 seconds MakeCheck FAIL 37.54 seconds MakeDistcheck PASS 185.76 seconds CheckValgrind FAIL 19.95 seconds bluezmakeextell FAIL 16.08 seconds IncrementalBuild FAIL 971.83 seconds ScanBuild FAIL 728.95 seconds Details ############################## Test: CheckPatch - FAIL Desc: Run checkpatch.pl script Output: [BlueZ,2/3] shared/shell: Add bt_shell_echo WARNING:PREFER_DEFINED_ATTRIBUTE_MACRO: Prefer __printf(1, 2) over __attribute__((format(printf, 1, 2))) #126: FILE: src/shared/shell.h:74: + ...) __attribute__((format(printf, 1, 2))); /github/workspace/src/src/13072605.patch total: 0 errors, 1 warnings, 29 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/src/13072605.patch has style problems, please review. NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS. ############################## Test: BluezMake - FAIL Desc: Build BlueZ Output: src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8276: src/shared/libshared_mainloop_la-shell.lo] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4482: all] Error 2 ############################## Test: MakeCheck - FAIL Desc: Run Bluez Make Check Output: src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8073: src/shared/libshared_glib_la-shell.lo] Error 1 make: *** [Makefile:11684: check] Error 2 ############################## Test: CheckValgrind - FAIL Desc: Run Bluez Make Check with Valgrind Output: src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8276: src/shared/libshared_mainloop_la-shell.lo] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:11684: check] Error 2 ############################## Test: bluezmakeextell - FAIL Desc: Build Bluez with External ELL Output: src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8276: src/shared/libshared_mainloop_la-shell.lo] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4482: all] Error 2 ############################## Test: IncrementalBuild - FAIL Desc: Incremental build with the patches in the series Output: [BlueZ,2/3] shared/shell: Add bt_shell_echo src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8276: src/shared/libshared_mainloop_la-shell.lo] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4482: all] Error 2 ############################## Test: ScanBuild - FAIL Desc: Run Scan Build Output: src/shared/ad.c:369:19: warning: Use of zero-allocated memory buf[(*pos)++] = ad_type; ^ 1 warning generated. src/shared/gatt-client.c:387:21: warning: Use of memory after it is freed gatt_db_unregister(op->client->db, op->db_id); ^~~~~~~~~~ src/shared/gatt-client.c:600:2: warning: Use of memory after it is freed discovery_op_complete(op, false, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:900:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1009:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1201:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1266:2: warning: Use of memory after it is freed discovery_op_complete(op, success, att_ecode); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1537:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:1542:2: warning: Use of memory after it is freed discover_all(op); ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2044:6: warning: Use of memory after it is freed if (read_db_hash(op)) { ^~~~~~~~~~~~~~~~ src/shared/gatt-client.c:2052:8: warning: Use of memory after it is freed discovery_op_ref(op), ^~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3135:2: warning: Use of memory after it is freed complete_write_long_op(req, success, 0, false); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/gatt-client.c:3157:2: warning: Use of memory after it is freed request_unref(req); ^~~~~~~~~~~~~~~~~~ 12 warnings generated. src/shared/shell.c: In function ‘bt_shell_echo’: src/shared/shell.c:585:2: error: ignoring return value of ‘vasprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 585 | vasprintf(&str, fmt, args); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ src/shared/shell.c:586:2: error: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result [-Werror=unused-result] 586 | asprintf(&str, COLOR_HIGHLIGHT "%s" COLOR_OFF, str); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[1]: *** [Makefile:8276: src/shared/libshared_mainloop_la-shell.lo] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:4482: all] Error 2 --- Regards, Linux Bluetooth
On Tue, 2022-12-13 at 16:21 -0800, Luiz Augusto von Dentz wrote: > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This makes transport.send command non-blocking by using timerfd > callback to initiate the transfers. This might be more elegantly done using a GMainLoop from glib, or if there's still this bizarre aversion to glib, implemented like glib's timeout functions. https://docs.gtk.org/glib/func.timeout_add.html Cheers
Hi Bastien, On Wed, Dec 14, 2022 at 1:13 AM Bastien Nocera <hadess@hadess.net> wrote: > > On Tue, 2022-12-13 at 16:21 -0800, Luiz Augusto von Dentz wrote: > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > > > This makes transport.send command non-blocking by using timerfd > > callback to initiate the transfers. > > This might be more elegantly done using a GMainLoop from glib, or if > there's still this bizarre aversion to glib, implemented like glib's > timeout functions. > > https://docs.gtk.org/glib/func.timeout_add.html Yeah, I thought I'd have to use nsec but msec should suffice so I can just use mainloop_add_timeout. > Cheers
diff --git a/client/player.c b/client/player.c index 95309e101148..2c15fb0c2d01 100644 --- a/client/player.c +++ b/client/player.c @@ -24,6 +24,7 @@ #include <sys/ioctl.h> #include <sys/uio.h> #include <wordexp.h> +#include <sys/timerfd.h> #include <glib.h> @@ -92,6 +93,7 @@ struct transport { int fd; struct io *io; uint32_t seq; + struct io *timer_io; }; static void endpoint_unregister(void *data) @@ -3004,6 +3006,8 @@ static void transport_close(struct transport *transport) return; close(transport->fd); + transport->fd = -1; + free(transport->filename); } @@ -3011,6 +3015,7 @@ static void transport_free(void *data) { struct transport *transport = data; + io_destroy(transport->timer_io); io_destroy(transport->io); free(transport); } @@ -3375,104 +3380,167 @@ static int open_file(const char *filename, int flags) return fd; } -#define NSEC_USEC(_t) (_t / 1000L) -#define SEC_USEC(_t) (_t * 1000000L) -#define TS_USEC(_ts) (SEC_USEC((_ts)->tv_sec) + NSEC_USEC((_ts)->tv_nsec)) - -static void send_wait(struct timespec *t_start, uint32_t us) +static int elapsed_time(bool reset, int *secs, int *nsecs) { - struct timespec t_now; - struct timespec t_diff; - int64_t delta_us; + static struct timespec start; + struct timespec curr; - /* Skip sleep at start */ - if (!us) - return; - - if (clock_gettime(CLOCK_MONOTONIC, &t_now) < 0) { - bt_shell_printf("clock_gettime: %s (%d)", strerror(errno), - errno); - return; + if (reset) { + if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) { + bt_shell_printf("clock_gettime: %s (%d)", + strerror(errno), errno); + return -errno; + } } - t_diff.tv_sec = t_now.tv_sec - t_start->tv_sec; - if (t_start->tv_nsec > t_now.tv_nsec) { - t_diff.tv_sec--; - t_now.tv_nsec += 1000000000L; - } - t_diff.tv_nsec = t_now.tv_nsec - t_start->tv_nsec; - - delta_us = us - TS_USEC(&t_diff); - - if (delta_us < 0) { - bt_shell_printf("Send is behind: %" PRId64 " us - skip sleep", - delta_us); - delta_us = 1000; - } - - usleep(delta_us); - - if (clock_gettime(CLOCK_MONOTONIC, t_start) < 0) + if (clock_gettime(CLOCK_MONOTONIC, &curr) < 0) { bt_shell_printf("clock_gettime: %s (%d)", strerror(errno), - errno); -} - -static int transport_send(struct transport *transport, int fd, - struct bt_iso_qos *qos) -{ - struct timespec t_start; - uint8_t *buf; - uint32_t num = 0; - - if (qos && clock_gettime(CLOCK_MONOTONIC, &t_start) < 0) { - bt_shell_printf("clock_gettime: %s (%d)", strerror(errno), - errno); + errno); return -errno; } - buf = malloc(transport->mtu[1]); - if (!buf) { - bt_shell_printf("malloc: %s (%d)", strerror(errno), errno); - return -ENOMEM; + *secs = curr.tv_sec - start.tv_sec; + *nsecs = curr.tv_nsec - start.tv_nsec; + if (*nsecs < 0) { + (*secs)--; + *nsecs += 1000000000; } - /* num of packets = latency (ms) / interval (us) */ - if (qos) - num = (qos->out.latency * 1000 / qos->out.interval); + return 0; +} - for (transport->seq = 0; ; transport->seq++) { +static int transport_send_seq(struct transport *transport, int fd, uint32_t num) +{ + uint8_t *buf; + uint32_t i; + + if (!num) + return 0; + + buf = malloc(transport->mtu[1]); + if (!buf) + return -ENOMEM; + + for (i = 0; i < num; i++, transport->seq++) { ssize_t ret; int queued; + int secs = 0, nsecs = 0; ret = read(fd, buf, transport->mtu[1]); if (ret <= 0) { if (ret < 0) bt_shell_printf("read failed: %s (%d)", strerror(errno), errno); - close(fd); + free(buf); return ret; } ret = send(transport->sk, buf, ret, 0); if (ret <= 0) { - bt_shell_printf("Send failed: %s (%d)", + bt_shell_printf("send failed: %s (%d)", strerror(errno), errno); + free(buf); return -errno; } + elapsed_time(!transport->seq, &secs, &nsecs); + ioctl(transport->sk, TIOCOUTQ, &queued); - bt_shell_printf("[seq %d] send: %zd bytes " + bt_shell_printf("[seq %d %d.%03ds] send: %zd bytes " "(TIOCOUTQ %d bytes)\n", - transport->seq, ret, queued); - - if (qos) { - if (transport->seq && !((transport->seq + 1) % num)) - send_wait(&t_start, num * qos->out.interval); - } + transport->seq, secs, + (nsecs + 500000) / 1000000, + ret, queued); } free(buf); + + return i; +} + +static bool transport_timer_read(struct io *io, void *user_data) +{ + struct transport *transport = user_data; + struct bt_iso_qos qos; + socklen_t len; + int ret, fd; + uint32_t num; + uint64_t exp; + + if (transport->fd < 0) + return false; + + fd = io_get_fd(io); + ret = read(fd, &exp, sizeof(exp)); + if (ret < 0) { + bt_shell_printf("Failed to read: %s (%d)\n", strerror(errno), + -errno); + return false; + } + + /* Read QoS if available */ + memset(&qos, 0, sizeof(qos)); + len = sizeof(qos); + if (getsockopt(transport->sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, + &len) < 0) { + bt_shell_printf("Failed to getsockopt(BT_ISO_QOS): %s (%d)\n", + strerror(errno), -errno); + return false; + } + + /* num of packets = latency (ms) / interval (us) */ + num = (qos.out.latency * 1000 / qos.out.interval); + + ret = transport_send_seq(transport, transport->fd, num); + if (ret < 0) { + bt_shell_printf("Unable to send: %s (%d)\n", + strerror(-ret), ret); + return false; + } + + if (!ret) { + bt_shell_printf("Transfer complete\n"); + transport_close(transport); + return false; + } + + return true; +} + +static int transport_send(struct transport *transport, int fd, + struct bt_iso_qos *qos) +{ + struct itimerspec ts; + int timer_fd; + + transport->seq = 0; + + if (!qos) + return transport_send_seq(transport, fd, UINT32_MAX); + + if (transport->fd >= 0) + return -EALREADY; + + timer_fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (timer_fd < 0) + return -errno; + + memset(&ts, 0, sizeof(ts)); + ts.it_value.tv_nsec = qos->out.latency * 1000000; + ts.it_interval.tv_nsec = qos->out.latency * 1000000; + + if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0) + return -errno; + + transport->fd = fd; + + transport->timer_io = io_new(timer_fd); + + io_set_read_handler(transport->timer_io, transport_timer_read, + transport, NULL); + + return transport_send_seq(transport, fd, 1); } static void cmd_send_transport(int argc, char *argv[]) @@ -3502,6 +3570,8 @@ static void cmd_send_transport(int argc, char *argv[]) } fd = open_file(argv[2], O_RDONLY); + if (fd < 0) + return bt_shell_noninteractive_quit(EXIT_FAILURE); bt_shell_printf("Sending ...\n"); @@ -3514,10 +3584,12 @@ static void cmd_send_transport(int argc, char *argv[]) else err = transport_send(transport, fd, &qos); - close(fd); - - if (err < 0) + if (err < 0) { + bt_shell_printf("Unable to send: %s (%d)", strerror(-err), + -err); + close(fd); return bt_shell_noninteractive_quit(EXIT_FAILURE); + } return bt_shell_noninteractive_quit(EXIT_SUCCESS); }
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This makes transport.send command non-blocking by using timerfd callback to initiate the transfers. --- client/player.c | 206 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 139 insertions(+), 67 deletions(-)