Diff between 16d48b4ddce33e50a38777f2b41c128168cb1fe2 and 3b75c3546e4fef943a0f0c0f0632531aade74d79

Changed Files

File Additions Deletions Status
android/avdtp.c +15 -1 modified

Full Patch

diff --git a/android/avdtp.c b/android/avdtp.c
index e4fd2b7..2252782 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -784,6 +784,10 @@ static void handle_unanswered_req(struct avdtp *session,
 	struct avdtp_local_sep *lsep;
 	struct avdtp_error err;
 
+	if (!session->req->timeout)
+		/* Request is in process */
+		return;
+
 	if (session->req->signal_id == AVDTP_ABORT) {
 		/* Avoid freeing the Abort request here */
 		DBG("handle_unanswered_req: Abort req, returning");
@@ -2017,6 +2021,9 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 		break;
 	}
 
+	/* Take a reference to protect against callback destroying session */
+	avdtp_ref(session);
+
 	if (session->in.message_type == AVDTP_MSG_TYPE_COMMAND) {
 		if (!avdtp_parse_cmd(session, session->in.transaction,
 					session->in.signal_id,
@@ -2031,21 +2038,25 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 			goto next;
 		}
 
+		avdtp_unref(session);
 		return TRUE;
 	}
 
 	if (session->req == NULL) {
 		error("No pending request, ignoring message");
+		avdtp_unref(session);
 		return TRUE;
 	}
 
 	if (header->transaction != session->req->transaction) {
 		error("Transaction label doesn't match");
+		avdtp_unref(session);
 		return TRUE;
 	}
 
 	if (session->in.signal_id != session->req->signal_id) {
 		error("Response signal doesn't match");
+		avdtp_unref(session);
 		return TRUE;
 	}
 
@@ -2085,7 +2096,10 @@ next:
 	pending_req_free(session->req);
 	session->req = NULL;
 
-	process_queue(session);
+	if (session->ref > 1)
+		process_queue(session);
+
+	avdtp_unref(session);
 
 	return TRUE;