[Live-devel] [PATCH] Register response callback prior sending RTSP command

Lionel Koenig lionel.koenig at codemill.se
Wed Dec 9 06:35:26 PST 2020


When sending RTSP command from another thread than the event loop (it is
actually unsupported see:
http://www.live555.com/liveMedia/faq.html#threads), the response of the
command might arrive prior the handler callback is registered. When that
happen, the handler will never be called even if the response was
received.
In this patch, the registration of the callback is done prior the
command is sent to ensure that the response callback is available when
the reply come back.
In case of failing sending the command, the response callback is
deregistered.
---
 liveMedia/RTSPClient.cpp | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/liveMedia/RTSPClient.cpp b/liveMedia/RTSPClient.cpp
index aaae3ba..8bdabc0 100644
--- a/liveMedia/RTSPClient.cpp
+++ b/liveMedia/RTSPClient.cpp
@@ -555,7 +555,20 @@ unsigned RTSPClient::sendRequest(RequestRecord* request) {
       delete[] origCmd;
     }
 
+    // Enqueue the request record, so that its response (when it comes) can be handled.
+    // However, note that we do not expect a response to a POST command with RTSP-over-HTTP, so don't enqueue that.
+    Boolean awaitingResponse = false;
+    if (fTunnelOverHTTPPortNum == 0 || strcmp(request->commandName(), "POST") != 0) {
+      fRequestsAwaitingResponse.enqueue(request);
+      awaitingResponse = true;
+    }
+
     if (write(cmd, strlen(cmd)) < 0) {
+      if (awaitingResponse) {
+        // Sending the request failed, unregister the response handler.
+        fRequestsAwaitingResponse.dequeue();
+        awaitingResponse = false;
+      }
       char const* errFmt = "%s write() failed: ";
       unsigned const errLength = strlen(errFmt) + strlen(request->commandName());
       char* err = new char[errLength];
@@ -565,13 +578,8 @@ unsigned RTSPClient::sendRequest(RequestRecord* request) {
       break;
     }
 
-    // The command send succeeded, so enqueue the request record, so that its response (when it comes) can be handled.
-    // However, note that we do not expect a response to a POST command with RTSP-over-HTTP, so don't enqueue that.
     int cseq = request->cseq();
-
-    if (fTunnelOverHTTPPortNum == 0 || strcmp(request->commandName(), "POST") != 0) {
-      fRequestsAwaitingResponse.enqueue(request);
-    } else {
+    if (!awaitingResponse) {
       delete request;
     }
 
-- 


More information about the live-devel mailing list