rtsp_conn_info *previous_principal_conn = principal_conn;
principal_conn = NULL; // no longer the principal conn
pthread_cancel(previous_principal_conn->thread);
+ // the previous principal thread will block on the principal conn lock when exiting
+ // so it's important not to wait for it here, e.g. don't put in a pthread_join here.
+ // threads are garbage-collected later
usleep(1000000); // don't know why this delay is needed.
principal_conn = conn; // make the conn the new principal_conn
response = 1; // interrupted an existing session
}
clear_ptp_clock();
}
+
+ // only update these things if you're (still) the principal conn
+ pthread_rwlock_rdlock(&principal_conn_lock); // don't let the principal_conn be changed
+ pthread_cleanup_push(rwlock_unlock, (void *)&principal_conn_lock);
+ if (principal_conn == conn) {
+ if (conn->airplay_stream_category == ptp_stream) {
+ config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
+ build_bonjour_strings(conn);
+ debug(2, "Connection %d: TEARDOWN mdns_update on %s.", conn->connection_number,
+ get_category_string(conn->airplay_stream_category));
+ mdns_update(NULL, secondary_txt_records);
+ }
+ principal_conn = NULL; // stop being principal_conn
+ }
+ pthread_cleanup_pop(1); // release the principal_conn lock
+ debug(2, "Connection %d: TEARDOWN %s -- close the connection complete", conn->connection_number,
+ get_category_string(conn->airplay_stream_category));
}
void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
get_category_string(conn->airplay_stream_category));
teardown_phase_one(conn); // try to do phase one anyway
teardown_phase_two(conn);
-
- // only update these things if you're (still) the principal conn
- pthread_rwlock_rdlock(&principal_conn_lock); // don't let the principal_conn be changed
- pthread_cleanup_push(rwlock_unlock, (void *)&principal_conn_lock);
- if ((principal_conn == conn) && (conn->airplay_stream_category == ptp_stream)) {
- config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
- build_bonjour_strings(conn);
- debug(2, "Connection %d: TEARDOWN mdns_update on %s.", conn->connection_number,
- get_category_string(conn->airplay_stream_category));
- mdns_update(NULL, secondary_txt_records);
- }
- pthread_cleanup_pop(1); // release the principal_conn lock
- debug(2, "Connection %d: TEARDOWN %s -- close the connection complete",
- conn->connection_number, get_category_string(conn->airplay_stream_category));
- release_play_lock(conn);
}
-
plist_free(messagePlist);
resp->respcode = 200;
} else {
free(conn->dacp_active_remote);
conn->dacp_active_remote = NULL;
}
-}
-void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
- rtsp_message *resp) {
- debug_log_rtsp_message(2, "TEARDOWN request", req);
- debug(2, "Connection %d: TEARDOWN", conn->connection_number);
- debug(3,
- "TEARDOWN: synchronously terminating the player thread of RTSP conversation thread %d (2).",
- conn->connection_number);
- teardown(conn);
-
-#ifdef CONFIG_AIRPLAY_2
// only update these things if you're (still) the principal conn
pthread_rwlock_rdlock(&principal_conn_lock); // don't let the principal_conn be changed
pthread_cleanup_push(rwlock_unlock, (void *)&principal_conn_lock);
if (principal_conn == conn) {
+#ifdef CONFIG_AIRPLAY_2
config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
build_bonjour_strings(conn);
mdns_update(NULL, secondary_txt_records);
+#endif
+ principal_conn = NULL; // stop being principal_conn
}
pthread_cleanup_pop(1); // release the principal_conn lock
-#endif
-
- release_play_lock(conn);
+}
+void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
+ rtsp_message *resp) {
+ debug_log_rtsp_message(2, "TEARDOWN request", req);
+ debug(2, "Connection %d: TEARDOWN", conn->connection_number);
+ debug(3,
+ "TEARDOWN: synchronously terminating the player thread of RTSP conversation thread %d (2).",
+ conn->connection_number);
+ teardown(conn);
resp->respcode = 200;
msg_add_header(resp, "Connection", "close");
debug(3, "TEARDOWN: successful termination of playing thread of RTSP conversation thread %d.",
conn->connection_number);
- //} else {
- // warn("Connection %d TEARDOWN received without having the player (no ANNOUNCE?)",
- // conn->connection_number);
- // resp->respcode = 451;
- // }
// debug(1,"Bogus exit for valgrind -- remember to comment it out!.");
// exit(EXIT_SUCCESS);
}
pthread_mutex_destroy(&conn->watchdog_mutex);
debug(2, "Connection %d: Closed.", conn->connection_number);
- conn->running = 0;
+ conn->running = 0; // for the garbage collector
pthread_setcancelstate(oldState, NULL);
}
}