@@ -430,7 +430,8 @@ int pc_queue_add_item(pc_queue *the_queue, const void *the_stuff, int block) {
430
430
} else
431
431
rc = pthread_mutex_lock (& the_queue -> pc_queue_lock );
432
432
if (rc )
433
- debug (1 , "Error locking for pc_queue_add_item" );
433
+ debug (1 , "Error %d (\"%s\") locking for pc_queue_add_item. Block is %d." , rc , strerror (rc ),
434
+ block );
434
435
pthread_cleanup_push (pc_queue_cleanup_handler , (void * )the_queue );
435
436
// leave this out if you want this to return if the queue is already full
436
437
// irrespective of the block flag.
@@ -1687,7 +1688,7 @@ void handle_get_info(__attribute((unused)) rtsp_conn_info *conn, rtsp_message *r
1687
1688
hdr );
1688
1689
}
1689
1690
}
1690
-
1691
+
1691
1692
// In Stage 1, look for the DACP and Active-Remote
1692
1693
char * ar = msg_get_header (req , "Active-Remote" );
1693
1694
if (ar ) {
@@ -2101,8 +2102,8 @@ void handle_post(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
2101
2102
if (strcmp (req -> path , "/feedback" ) == 0 ) {
2102
2103
resp -> respcode = 501 ;
2103
2104
} else {
2104
- debug (1 , "Connection %d: Airplay 1. Unhandled POST %s Content-Length %d" , conn -> connection_number ,
2105
- req -> path , req -> contentlength );
2105
+ debug (1 , "Connection %d: Airplay 1. Unhandled POST %s Content-Length %d" ,
2106
+ conn -> connection_number , req -> path , req -> contentlength );
2106
2107
debug_log_rtsp_message (2 , "POST request" , req );
2107
2108
}
2108
2109
}
@@ -3085,7 +3086,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
3085
3086
// iap->ifa_name);
3086
3087
if ((iap -> ifa_addr ) && (iap -> ifa_netmask ) && (iap -> ifa_flags & IFF_UP ) &&
3087
3088
((iap -> ifa_flags & IFF_LOOPBACK ) == 0 ) &&
3088
- (config .interface == NULL || (strcmp (config .interface , iap -> ifa_name ) == 0 ))) {
3089
+ (config .interface == NULL || (strcmp (config .interface , iap -> ifa_name ) == 0 ))) {
3089
3090
char buf [INET6_ADDRSTRLEN + 1 ]; // +1 for a NUL
3090
3091
memset (buf , 0 , sizeof (buf ));
3091
3092
if (iap -> ifa_addr -> sa_family == AF_INET6 ) {
@@ -4081,13 +4082,9 @@ void metadata_pack_cleanup_function(void *arg) {
4081
4082
void metadata_thread_cleanup_function (__attribute__((unused )) void * arg ) {
4082
4083
// debug(2, "metadata_thread_cleanup_function called");
4083
4084
metadata_close ();
4084
- pc_queue_delete (& metadata_queue );
4085
4085
}
4086
4086
4087
4087
void * metadata_thread_function (__attribute__((unused )) void * ignore ) {
4088
- // create a pc_queue for passing information to a threaded metadata handler
4089
- pc_queue_init (& metadata_queue , (char * )& metadata_queue_items , sizeof (metadata_package ),
4090
- metadata_queue_size , "pipe" );
4091
4088
metadata_create_multicast_socket ();
4092
4089
metadata_package pack ;
4093
4090
pthread_cleanup_push (metadata_thread_cleanup_function , NULL );
@@ -4113,13 +4110,9 @@ void *metadata_thread_function(__attribute__((unused)) void *ignore) {
4113
4110
void metadata_multicast_thread_cleanup_function (__attribute__((unused )) void * arg ) {
4114
4111
// debug(2, "metadata_multicast_thread_cleanup_function called");
4115
4112
metadata_delete_multicast_socket ();
4116
- pc_queue_delete (& metadata_multicast_queue );
4117
4113
}
4118
4114
4119
4115
void * metadata_multicast_thread_function (__attribute__((unused )) void * ignore ) {
4120
- // create a pc_queue for passing information to a threaded metadata handler
4121
- pc_queue_init (& metadata_multicast_queue , (char * )& metadata_multicast_queue_items ,
4122
- sizeof (metadata_package ), metadata_multicast_queue_size , "multicast" );
4123
4116
metadata_create_multicast_socket ();
4124
4117
metadata_package pack ;
4125
4118
pthread_cleanup_push (metadata_multicast_thread_cleanup_function , NULL );
@@ -4154,13 +4147,9 @@ void metadata_hub_close(void) {}
4154
4147
void metadata_hub_thread_cleanup_function (__attribute__((unused )) void * arg ) {
4155
4148
// debug(2, "metadata_hub_thread_cleanup_function called");
4156
4149
metadata_hub_close ();
4157
- pc_queue_delete (& metadata_hub_queue );
4158
4150
}
4159
4151
4160
4152
void * metadata_hub_thread_function (__attribute__((unused )) void * ignore ) {
4161
- // create a pc_queue for passing information to a threaded metadata handler
4162
- pc_queue_init (& metadata_hub_queue , (char * )& metadata_hub_queue_items , sizeof (metadata_package ),
4163
- metadata_hub_queue_size , "hub" );
4164
4153
metadata_package pack ;
4165
4154
pthread_cleanup_push (metadata_hub_thread_cleanup_function , NULL );
4166
4155
while (1 ) {
@@ -4188,14 +4177,10 @@ void metadata_mqtt_close(void) {}
4188
4177
void metadata_mqtt_thread_cleanup_function (__attribute__((unused )) void * arg ) {
4189
4178
// debug(2, "metadata_mqtt_thread_cleanup_function called");
4190
4179
metadata_mqtt_close ();
4191
- pc_queue_delete (& metadata_mqtt_queue );
4192
4180
// debug(2, "metadata_mqtt_thread_cleanup_function done");
4193
4181
}
4194
4182
4195
4183
void * metadata_mqtt_thread_function (__attribute__((unused )) void * ignore ) {
4196
- // create a pc_queue for passing information to a threaded metadata handler
4197
- pc_queue_init (& metadata_mqtt_queue , (char * )& metadata_mqtt_queue_items , sizeof (metadata_package ),
4198
- metadata_mqtt_queue_size , "mqtt" );
4199
4184
metadata_package pack ;
4200
4185
pthread_cleanup_push (metadata_mqtt_thread_cleanup_function , NULL );
4201
4186
while (1 ) {
@@ -4242,24 +4227,39 @@ void metadata_init(void) {
4242
4227
if ((fd == -1 ) && (errno != ENXIO )) {
4243
4228
char errorstring [1024 ];
4244
4229
strerror_r (errno , (char * )errorstring , sizeof (errorstring ));
4245
- debug (1 , "metadata_hub_thread_function -- error %d (\"%s\") opening pipe: \"%s\"." , errno ,
4230
+ debug (1 , "metadata_init -- error %d (\"%s\") opening pipe: \"%s\"." , errno ,
4246
4231
(char * )errorstring , path );
4247
4232
warn ("can not open metadata pipe -- error %d (\"%s\") opening pipe: \"%s\"." , errno ,
4248
4233
(char * )errorstring , path );
4249
4234
}
4250
4235
free (path );
4236
+
4237
+ // initialise the metadata queues first, otherwise the might be a race condition
4238
+ // create a pc_queue for the metadata pipe
4239
+ pc_queue_init (& metadata_queue , (char * )& metadata_queue_items , sizeof (metadata_package ),
4240
+ metadata_queue_size , "pipe" );
4241
+
4251
4242
if (pthread_create (& metadata_thread , NULL , metadata_thread_function , NULL ) != 0 )
4252
4243
debug (1 , "Failed to create metadata thread!" );
4253
4244
4245
+ // create a pc_queue for the metadata_multicast_queue
4246
+ pc_queue_init (& metadata_multicast_queue , (char * )& metadata_multicast_queue_items ,
4247
+ sizeof (metadata_package ), metadata_multicast_queue_size , "multicast" );
4254
4248
if (pthread_create (& metadata_multicast_thread , NULL , metadata_multicast_thread_function ,
4255
4249
NULL ) != 0 )
4256
4250
debug (1 , "Failed to create metadata multicast thread!" );
4257
4251
}
4258
4252
#ifdef CONFIG_METADATA_HUB
4253
+ // create a pc_queue for the metadata hub
4254
+ pc_queue_init (& metadata_hub_queue , (char * )& metadata_hub_queue_items , sizeof (metadata_package ),
4255
+ metadata_hub_queue_size , "hub" );
4259
4256
if (pthread_create (& metadata_hub_thread , NULL , metadata_hub_thread_function , NULL ) != 0 )
4260
4257
debug (1 , "Failed to create metadata hub thread!" );
4261
4258
#endif
4262
4259
#ifdef CONFIG_MQTT
4260
+ // create a pc_queue for the MQTT handler
4261
+ pc_queue_init (& metadata_mqtt_queue , (char * )& metadata_mqtt_queue_items , sizeof (metadata_package ),
4262
+ metadata_mqtt_queue_size , "mqtt" );
4263
4263
if (pthread_create (& metadata_mqtt_thread , NULL , metadata_mqtt_thread_function , NULL ) != 0 )
4264
4264
debug (1 , "Failed to create metadata mqtt thread!" );
4265
4265
#endif
@@ -4273,26 +4273,30 @@ void metadata_stop(void) {
4273
4273
// debug(2, "metadata stop mqtt thread.");
4274
4274
pthread_cancel (metadata_mqtt_thread );
4275
4275
pthread_join (metadata_mqtt_thread , NULL );
4276
+ pc_queue_delete (& metadata_mqtt_queue );
4276
4277
// debug(2, "metadata stop mqtt done.");
4277
4278
#endif
4278
4279
#ifdef CONFIG_METADATA_HUB
4279
4280
// debug(2, "metadata stop hub thread.");
4280
4281
pthread_cancel (metadata_hub_thread );
4281
4282
pthread_join (metadata_hub_thread , NULL );
4282
4283
// debug(2, "metadata stop hub done.");
4284
+ pc_queue_delete (& metadata_hub_queue );
4283
4285
#endif
4284
4286
if (config .metadata_enabled ) {
4285
4287
// debug(2, "metadata stop multicast thread.");
4286
4288
if (metadata_multicast_thread ) {
4287
4289
pthread_cancel (metadata_multicast_thread );
4288
4290
pthread_join (metadata_multicast_thread , NULL );
4289
4291
// debug(2, "metadata stop multicast done.");
4292
+ pc_queue_delete (& metadata_multicast_queue );
4290
4293
}
4291
4294
if (metadata_thread ) {
4292
4295
// debug(2, "metadata stop metadata_thread thread.");
4293
4296
pthread_cancel (metadata_thread );
4294
4297
pthread_join (metadata_thread , NULL );
4295
4298
// debug(2, "metadata_stop finished successfully.");
4299
+ pc_queue_delete (& metadata_queue );
4296
4300
}
4297
4301
}
4298
4302
}
@@ -4343,6 +4347,8 @@ int send_metadata_to_queue(pc_queue *queue, uint32_t type, uint32_t code, char *
4343
4347
if (data )
4344
4348
pack .data = memdup (data , length ); // only if it's not a null
4345
4349
}
4350
+
4351
+ // debug(1, "send_metadata_to_queue %x/%x", type, code);
4346
4352
int rc = pc_queue_add_item (queue , & pack , block );
4347
4353
if (rc != 0 ) {
4348
4354
if (pack .carrier ) {
@@ -5642,22 +5648,33 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
5642
5648
} else {
5643
5649
size_of_reply = sizeof (SOCKADDR );
5644
5650
if (getsockname (conn -> fd , (struct sockaddr * )& conn -> local , & size_of_reply ) == 0 ) {
5651
+
5652
+ // skip this stuff in OpenBSD
5645
5653
#ifndef COMPILE_FOR_OPENBSD
5646
5654
// Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
5647
5655
5648
5656
// turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
5649
5657
// before giving up an ETIMEOUT error is returned if the keepalive check fails
5650
5658
5659
+ // if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
5660
+ // otherwise just wait a little while longer
5661
+
5662
+ #ifdef TCP_KEEPINTVL
5651
5663
int keepAliveIdleTime = 35 ; // wait this many seconds before checking for a dropped client
5652
5664
int keepAliveCount = 5 ; // check this many times
5653
5665
int keepAliveInterval = 5 ; // wait this many seconds between checks
5666
+ #else
5667
+ int keepAliveIdleTime = 60 ; // wait this many seconds before dropping a client
5668
+ #endif
5654
5669
5670
+ // --- the following is a bit too complicated
5671
+ // decide to use IPPROTO_TCP or SOL_TCP
5655
5672
#if defined COMPILE_FOR_BSD || defined COMPILE_FOR_OSX
5656
5673
#define SOL_OPTION IPPROTO_TCP
5657
5674
#else
5658
5675
#define SOL_OPTION SOL_TCP
5659
5676
#endif
5660
-
5677
+ // decide to use TCP_KEEPALIVE or TCP_KEEPIDLE
5661
5678
#ifdef COMPILE_FOR_OSX
5662
5679
#define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPALIVE
5663
5680
#else
@@ -5666,17 +5683,20 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
5666
5683
5667
5684
if (setsockopt (conn -> fd , SOL_OPTION , KEEP_ALIVE_OR_IDLE_OPTION ,
5668
5685
(void * )& keepAliveIdleTime , sizeof (keepAliveIdleTime ))) {
5669
- debug (1 , "can't set the keepidle wait time" );
5686
+ debug (1 , "can't set the keepAliveIdleTime wait time" );
5670
5687
}
5671
-
5688
+ // ---
5689
+ // if TCP_KEEPINTVL is defined...
5690
+ #ifdef TCP_KEEPINTVL
5672
5691
if (setsockopt (conn -> fd , SOL_OPTION , TCP_KEEPCNT , (void * )& keepAliveCount ,
5673
5692
sizeof (keepAliveCount ))) {
5674
- debug (1 , "can't set the keepidle missing count" );
5693
+ debug (1 , "can't set the keepAliveCount count" );
5675
5694
}
5676
5695
if (setsockopt (conn -> fd , SOL_OPTION , TCP_KEEPINTVL , (void * )& keepAliveInterval ,
5677
5696
sizeof (keepAliveInterval ))) {
5678
- debug (1 , "can't set the keepidle missing count interval" );
5697
+ debug (1 , "can't set the keepAliveCount count interval" );
5679
5698
};
5699
+ #endif
5680
5700
#endif
5681
5701
5682
5702
// initialise the connection info
@@ -5736,8 +5756,8 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
5736
5756
pthread_cleanup_pop (1 ); // should never happen
5737
5757
} else {
5738
5758
die ("could not establish a service on port %d -- program terminating. Is another instance of "
5739
- "Shairport Sync running on this device?" ,
5740
- config .port );
5759
+ "Shairport Sync running on this device?" ,
5760
+ config .port );
5741
5761
}
5742
5762
debug (1 , "Oops -- fell out of the RTSP select loop" );
5743
5763
pthread_exit (NULL );
0 commit comments