Browse Source

Loosened write lock to prevent usrsctp deadlock

Paul-Louis Ageneau 5 years ago
parent
commit
2c58fd7659
2 changed files with 6 additions and 5 deletions
  1. 3 2
      src/sctptransport.cpp
  2. 3 3
      src/sctptransport.hpp

+ 3 - 2
src/sctptransport.cpp

@@ -246,8 +246,6 @@ void SctpTransport::flush() {
 void SctpTransport::reset(unsigned int stream) {
 void SctpTransport::reset(unsigned int stream) {
 	PLOG_DEBUG << "SCTP resetting stream " << stream;
 	PLOG_DEBUG << "SCTP resetting stream " << stream;
 
 
-	std::unique_lock lock(mWriteMutex);
-	mWritten = false;
 	using srs_t = struct sctp_reset_streams;
 	using srs_t = struct sctp_reset_streams;
 	const size_t len = sizeof(srs_t) + sizeof(uint16_t);
 	const size_t len = sizeof(srs_t) + sizeof(uint16_t);
 	byte buffer[len] = {};
 	byte buffer[len] = {};
@@ -255,7 +253,10 @@ void SctpTransport::reset(unsigned int stream) {
 	srs.srs_flags = SCTP_STREAM_RESET_OUTGOING;
 	srs.srs_flags = SCTP_STREAM_RESET_OUTGOING;
 	srs.srs_number_streams = 1;
 	srs.srs_number_streams = 1;
 	srs.srs_stream_list[0] = uint16_t(stream);
 	srs.srs_stream_list[0] = uint16_t(stream);
+
+	mWritten = false;
 	if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_RESET_STREAMS, &srs, len) == 0) {
 	if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_RESET_STREAMS, &srs, len) == 0) {
+		std::unique_lock lock(mWriteMutex); // locking before setsockopt might deadlock usrsctp...
 		mWrittenCondition.wait_for(lock, 1000ms,
 		mWrittenCondition.wait_for(lock, 1000ms,
 		                           [&]() { return mWritten || mState != State::Connected; });
 		                           [&]() { return mWritten || mState != State::Connected; });
 	} else {
 	} else {

+ 3 - 3
src/sctptransport.hpp

@@ -99,9 +99,9 @@ private:
 	std::map<uint16_t, size_t> mBufferedAmount;
 	std::map<uint16_t, size_t> mBufferedAmount;
 	amount_callback mBufferedAmountCallback;
 	amount_callback mBufferedAmountCallback;
 
 
-	std::recursive_mutex mWriteMutex;
-	std::condition_variable_any mWrittenCondition;
-	bool mWritten = false;
+	std::mutex mWriteMutex;
+	std::condition_variable mWrittenCondition;
+	std::atomic<bool> mWritten = false; // written outside lock
 	bool mWrittenOnce = false;
 	bool mWrittenOnce = false;
 
 
 	state_callback mStateChangeCallback;
 	state_callback mStateChangeCallback;