Skip to content

Commit 419ff39

Browse files
committed
Remove watchdog stuff. USe the session timeout to set the TCP keep intervals and stuff. Change response to ETIMEDOUT to rtsp_read_request_response_immediate_shutdown_requested.
1 parent fe8c6dd commit 419ff39

File tree

1 file changed

+35
-91
lines changed

1 file changed

+35
-91
lines changed

rtsp.c

Lines changed: 35 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (c) James Laird 2013
44
55
* Modifications associated with audio synchronization, multithreading and
6-
* metadata handling copyright (c) Mike Brady 2014-2023
6+
* metadata handling copyright (c) Mike Brady 2014-2024
77
* All rights reserved.
88
*
99
* Permission is hereby granted, free of charge, to any person
@@ -612,57 +612,6 @@ int get_play_lock(rtsp_conn_info *conn, int allow_session_interruption) {
612612
return response;
613613
}
614614

615-
void player_watchdog_thread_cleanup_handler(void *arg) {
616-
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
617-
debug(3, "Connection %d: Watchdog Exit.", conn->connection_number);
618-
}
619-
620-
void *player_watchdog_thread_code(void *arg) {
621-
pthread_cleanup_push(player_watchdog_thread_cleanup_handler, arg);
622-
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
623-
do {
624-
usleep(2000000); // check every two seconds
625-
// debug(3, "Connection %d: Check the thread is doing something...", conn->connection_number);
626-
#ifdef CONFIG_AIRPLAY_2
627-
if ((config.dont_check_timeout == 0) && (config.timeout != 0) && (conn->airplay_type == ap_1)) {
628-
#else
629-
if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
630-
#endif
631-
debug_mutex_lock(&conn->watchdog_mutex, 1000, 0);
632-
uint64_t last_watchdog_bark_time = conn->watchdog_bark_time;
633-
debug_mutex_unlock(&conn->watchdog_mutex, 0);
634-
if (last_watchdog_bark_time != 0) {
635-
uint64_t time_since_last_bark =
636-
(get_absolute_time_in_ns() - last_watchdog_bark_time) / 1000000000;
637-
uint64_t ct = config.timeout; // go from int to 64-bit int
638-
639-
if (time_since_last_bark >= ct) {
640-
conn->watchdog_barks++;
641-
if (conn->watchdog_barks == 1) {
642-
// debuglev = 3; // tell us everything.
643-
debug(1,
644-
"Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
645-
"of the heart\".",
646-
conn->connection_number);
647-
conn->stop = 1;
648-
pthread_cancel(conn->thread);
649-
} else if (conn->watchdog_barks == 3) {
650-
if ((config.cmd_unfixable) && (config.unfixable_error_reported == 0)) {
651-
config.unfixable_error_reported = 1;
652-
command_execute(config.cmd_unfixable, "unable_to_cancel_play_session", 1);
653-
} else {
654-
die("an unrecoverable error, \"unable_to_cancel_play_session\", has been detected.",
655-
conn->connection_number);
656-
}
657-
}
658-
}
659-
}
660-
}
661-
} while (1);
662-
pthread_cleanup_pop(0); // should never happen
663-
pthread_exit(NULL);
664-
}
665-
666615
static void track_thread(rtsp_conn_info *conn) {
667616
debug_mutex_lock(&conns_lock, 1000000, 3);
668617
// look for an empty slot first
@@ -1349,8 +1298,11 @@ enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_mes
13491298
continue;
13501299
}
13511300
if (errno == ETIMEDOUT) {
1352-
debug(1, "Connection %d: ETIMEDOUT -- keepalive timeout.", conn->connection_number);
1353-
reply = rtsp_read_request_response_channel_closed;
1301+
debug(1,
1302+
"Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
1303+
"of the heart\".",
1304+
conn->connection_number);
1305+
reply = rtsp_read_request_response_immediate_shutdown_requested;
13541306
// Note: the socket will be closed when the thread exits
13551307
goto shutdown;
13561308
}
@@ -2116,7 +2068,7 @@ struct pairings {
21162068
uint8_t public_key[32];
21172069

21182070
struct pairings *next;
2119-
} * pairings;
2071+
} *pairings;
21202072

21212073
static struct pairings *pairing_find(const char *device_id) {
21222074
for (struct pairings *pairing = pairings; pairing; pairing = pairing->next) {
@@ -5113,7 +5065,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
51135065
if (conn != NULL) {
51145066
int oldState;
51155067
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
5116-
debug(2, "Connection %d: %s rtsp_conversation_thread_func_cleanup_function called.",
5068+
debug(3, "Connection %d: %s rtsp_conversation_thread_func_cleanup_function called.",
51175069
conn->connection_number, get_category_string(conn->airplay_stream_category));
51185070
#ifdef CONFIG_AIRPLAY_2
51195071
// AP2
@@ -5205,14 +5157,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
52055157
if (rc)
52065158
debug(1, "Connection %d: error %d destroying flush_mutex.", conn->connection_number, rc);
52075159

5208-
debug(3, "Cancel watchdog thread.");
5209-
pthread_cancel(conn->player_watchdog_thread);
5210-
debug(3, "Join watchdog thread.");
5211-
pthread_join(conn->player_watchdog_thread, NULL);
5212-
debug(3, "Delete watchdog mutex.");
5213-
pthread_mutex_destroy(&conn->watchdog_mutex);
5214-
5215-
debug(2, "Connection %d: Closed.", conn->connection_number);
5160+
debug(3, "Connection %d: Closed.", conn->connection_number);
52165161
conn->running = 0; // for the garbage collector
52175162
pthread_setcancelstate(oldState, NULL);
52185163
}
@@ -5226,11 +5171,6 @@ void msg_cleanup_function(void *arg) {
52265171
static void *rtsp_conversation_thread_func(void *pconn) {
52275172
rtsp_conn_info *conn = pconn;
52285173

5229-
// create the watchdog mutex, initialise the watchdog time and start the watchdog thread;
5230-
conn->watchdog_bark_time = get_absolute_time_in_ns();
5231-
pthread_mutex_init(&conn->watchdog_mutex, NULL);
5232-
pthread_create(&conn->player_watchdog_thread, NULL, &player_watchdog_thread_code, (void *)conn);
5233-
52345174
int rc = pthread_mutex_init(&conn->flush_mutex, NULL);
52355175
if (rc)
52365176
die("Connection %d: error %d initialising flush_mutex.", conn->connection_number, rc);
@@ -5649,22 +5589,26 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
56495589
size_of_reply = sizeof(SOCKADDR);
56505590
if (getsockname(conn->fd, (struct sockaddr *)&conn->local, &size_of_reply) == 0) {
56515591

5592+
if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
56525593
// skip this stuff in OpenBSD
56535594
#ifndef COMPILE_FOR_OPENBSD
5654-
// Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
5595+
// Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
56555596

5656-
// turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
5657-
// before giving up an ETIMEOUT error is returned if the keepalive check fails
5597+
// turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
5598+
// before giving up an ETIMEOUT error is returned if the keepalive check fails
56585599

5659-
// if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
5660-
// otherwise just wait a little while longer
5600+
// if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
5601+
// otherwise just wait a little while longer
56615602

56625603
#ifdef TCP_KEEPINTVL
5663-
int keepAliveIdleTime = 35; // wait this many seconds before checking for a dropped client
5664-
int keepAliveCount = 5; // check this many times
5665-
int keepAliveInterval = 5; // wait this many seconds between checks
5604+
int keepAliveIdleTime =
5605+
config.timeout -
5606+
5 * 5; // wait this many seconds before checking for a dropped client
5607+
int keepAliveCount = 5; // check this many times
5608+
int keepAliveInterval = 5; // wait this many seconds between checks
56665609
#else
5667-
int keepAliveIdleTime = 60; // wait this many seconds before dropping a client
5610+
int keepAliveIdleTime =
5611+
config.timeout; // wait this many seconds before dropping a client
56685612
#endif
56695613

56705614
// --- the following is a bit too complicated
@@ -5681,24 +5625,24 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
56815625
#define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPIDLE
56825626
#endif
56835627

5684-
if (setsockopt(conn->fd, SOL_OPTION, KEEP_ALIVE_OR_IDLE_OPTION,
5685-
(void *)&keepAliveIdleTime, sizeof(keepAliveIdleTime))) {
5686-
debug(1, "can't set the keepAliveIdleTime wait time");
5687-
}
5628+
if (setsockopt(conn->fd, SOL_OPTION, KEEP_ALIVE_OR_IDLE_OPTION,
5629+
(void *)&keepAliveIdleTime, sizeof(keepAliveIdleTime))) {
5630+
debug(1, "can't set the keepAliveIdleTime wait time");
5631+
}
56885632
// ---
56895633
// if TCP_KEEPINTVL is defined...
56905634
#ifdef TCP_KEEPINTVL
5691-
if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPCNT, (void *)&keepAliveCount,
5692-
sizeof(keepAliveCount))) {
5693-
debug(1, "can't set the keepAliveCount count");
5694-
}
5695-
if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPINTVL, (void *)&keepAliveInterval,
5696-
sizeof(keepAliveInterval))) {
5697-
debug(1, "can't set the keepAliveCount count interval");
5698-
};
5635+
if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPCNT, (void *)&keepAliveCount,
5636+
sizeof(keepAliveCount))) {
5637+
debug(1, "can't set the keepAliveCount count");
5638+
}
5639+
if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPINTVL, (void *)&keepAliveInterval,
5640+
sizeof(keepAliveInterval))) {
5641+
debug(1, "can't set the keepAliveCount count interval");
5642+
};
56995643
#endif
57005644
#endif
5701-
5645+
}
57025646
// initialise the connection info
57035647
void *client_addr = NULL, *self_addr = NULL;
57045648
conn->connection_ip_family = conn->local.SAFAMILY;

0 commit comments

Comments
 (0)