3
3
* Copyright (c) James Laird 2013
4
4
5
5
* 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
7
7
* All rights reserved.
8
8
*
9
9
* 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) {
612
612
return response ;
613
613
}
614
614
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
-
666
615
static void track_thread (rtsp_conn_info * conn ) {
667
616
debug_mutex_lock (& conns_lock , 1000000 , 3 );
668
617
// look for an empty slot first
@@ -1349,8 +1298,11 @@ enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_mes
1349
1298
continue ;
1350
1299
}
1351
1300
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 ;
1354
1306
// Note: the socket will be closed when the thread exits
1355
1307
goto shutdown ;
1356
1308
}
@@ -2116,7 +2068,7 @@ struct pairings {
2116
2068
uint8_t public_key [32 ];
2117
2069
2118
2070
struct pairings * next ;
2119
- } * pairings ;
2071
+ } * pairings ;
2120
2072
2121
2073
static struct pairings * pairing_find (const char * device_id ) {
2122
2074
for (struct pairings * pairing = pairings ; pairing ; pairing = pairing -> next ) {
@@ -5113,7 +5065,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
5113
5065
if (conn != NULL ) {
5114
5066
int oldState ;
5115
5067
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." ,
5117
5069
conn -> connection_number , get_category_string (conn -> airplay_stream_category ));
5118
5070
#ifdef CONFIG_AIRPLAY_2
5119
5071
// AP2
@@ -5205,14 +5157,7 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
5205
5157
if (rc )
5206
5158
debug (1 , "Connection %d: error %d destroying flush_mutex." , conn -> connection_number , rc );
5207
5159
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 );
5216
5161
conn -> running = 0 ; // for the garbage collector
5217
5162
pthread_setcancelstate (oldState , NULL );
5218
5163
}
@@ -5226,11 +5171,6 @@ void msg_cleanup_function(void *arg) {
5226
5171
static void * rtsp_conversation_thread_func (void * pconn ) {
5227
5172
rtsp_conn_info * conn = pconn ;
5228
5173
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
-
5234
5174
int rc = pthread_mutex_init (& conn -> flush_mutex , NULL );
5235
5175
if (rc )
5236
5176
die ("Connection %d: error %d initialising flush_mutex." , conn -> connection_number , rc );
@@ -5649,22 +5589,26 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
5649
5589
size_of_reply = sizeof (SOCKADDR );
5650
5590
if (getsockname (conn -> fd , (struct sockaddr * )& conn -> local , & size_of_reply ) == 0 ) {
5651
5591
5592
+ if ((config .dont_check_timeout == 0 ) && (config .timeout != 0 )) {
5652
5593
// skip this stuff in OpenBSD
5653
5594
#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.
5655
5596
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
5658
5599
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
5661
5602
5662
5603
#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
5666
5609
#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
5668
5612
#endif
5669
5613
5670
5614
// --- the following is a bit too complicated
@@ -5681,24 +5625,24 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
5681
5625
#define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPIDLE
5682
5626
#endif
5683
5627
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
+ }
5688
5632
// ---
5689
5633
// if TCP_KEEPINTVL is defined...
5690
5634
#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
+ };
5699
5643
#endif
5700
5644
#endif
5701
-
5645
+ }
5702
5646
// initialise the connection info
5703
5647
void * client_addr = NULL , * self_addr = NULL ;
5704
5648
conn -> connection_ip_family = conn -> local .SAFAMILY ;
0 commit comments