}
static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
- debug(2, "Connection %d: ANNOUNCE", conn->connection_number);
+ debug(3, "Connection %d: ANNOUNCE", conn->connection_number);
int have_the_player = 0;
int should_wait = 0; // this will be true if you're trying to break in to the current session
have_the_player = 1;
warn("Duplicate ANNOUNCE, by the look of it!");
} else if (playing_conn->stop) {
- debug(1, "Connection %d: ANNOUNCE: already shutting down; waiting for it...",
- playing_conn->connection_number);
+ debug(1, "Connection %d ANNOUNCE is waiting for connection %d to shut down.",
+ conn->connection_number, playing_conn->connection_number);
should_wait = 1;
} else if (config.allow_session_interruption == 1) {
debug(2, "Connection %d: ANNOUNCE: asking playing connection %d to shut down.",
void rtsp_conversation_thread_cleanup_function(void *arg) {
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
- // debug(1, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.",
- // conn->connection_number);
+ int oldState;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
+
+ debug(3, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.",
+ conn->connection_number);
if (conn->player_thread)
player_stop(conn);
+
if (conn->fd > 0) {
debug(3, "Connection %d: closing fd %d.", conn->connection_number, conn->fd);
close(conn->fd);
debug(2, "Cancel watchdog thread.");
pthread_cancel(conn->player_watchdog_thread);
- int oldState;
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
debug(2, "Join watchdog thread.");
pthread_join(conn->player_watchdog_thread, NULL);
- pthread_setcancelstate(oldState, NULL);
debug(2, "Delete watchdog mutex.");
pthread_mutex_destroy(&conn->watchdog_mutex);
debug(2, "Connection %d: RTSP thread terminated.", conn->connection_number);
conn->running = 0;
+ pthread_setcancelstate(oldState, NULL);
}
void msg_cleanup_function(void *arg) {
die("Connection %d: error %d initialising flow control condition variable.",
conn->connection_number, rc);
+ // nothing before this is cancellable
+ pthread_cleanup_push(rtsp_conversation_thread_cleanup_function, (void *)conn);
+
rtp_initialise(conn);
char *hdr = NULL;
int rtsp_read_request_attempt_count = 1; // 1 means exit immediately
rtsp_message *req, *resp;
- pthread_cleanup_push(rtsp_conversation_thread_cleanup_function, (void *)conn);
while (conn->stop == 0) {
int debug_level = 3; // for printing the request and response
reply = rtsp_read_request(conn, &req);
debug(1, "Connection %d: Unable to write an RTSP message response. Terminating the "
"connection.",
conn->connection_number);
+ struct linger so_linger;
+ so_linger.l_onoff = 1; // "true"
+ so_linger.l_linger = 0;
+ err = setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
+ if (err)
+ debug(1, "Could not set the RTSP socket to abort due to a write error on closing.");
conn->stop = 1;
// if (debuglev >= 1)
// debuglev = 3; // see what happens next
rtsp_read_request_attempt_count--;
if (rtsp_read_request_attempt_count == 0) {
tstop = 1;
- // if ((reply == rtsp_read_request_response_read_error) && (debuglev != 0))
+ if (reply == rtsp_read_request_response_read_error) {
+ struct linger so_linger;
+ so_linger.l_onoff = 1; // "true"
+ so_linger.l_linger = 0;
+ int err = setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
+ if (err)
+ debug(1, "Could not set the RTSP socket to abort due to a read error on closing.");
+ }
// debuglev = 3; // see what happens next
} else {
if (reply == rtsp_read_request_response_channel_closed)
*/
void rtsp_listen_loop_cleanup_handler(__attribute__((unused)) void *arg) {
+ int oldState;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
debug(1, "rtsp_listen_loop_cleanup_handler called.");
cancel_all_RTSP_threads();
int *sockfd = (int *)arg;
mdns_unregister();
if (sockfd)
free(sockfd);
+ pthread_setcancelstate(oldState, NULL);
}
void rtsp_listen_loop(void) {
+ int oldState;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
struct addrinfo hints, *info, *p;
char portstr[6];
int *sockfd = NULL;
mdns_register();
- // printf("Listening for connections.");
- // shairport_startup_complete();
-
+ pthread_setcancelstate(oldState, NULL);
int acceptfd;
struct timeval tv;
pthread_cleanup_push(rtsp_listen_loop_cleanup_handler, (void *)sockfd);
}
} while (1);
- pthread_cleanup_pop(0);
+ pthread_cleanup_pop(1); // should never happen
debug(1, "Oops -- fell out of the RTSP select loop");
}