From 79a74ea7a578e8c86ae057592ee02e2973174b4e Mon Sep 17 00:00:00 2001
From: paweldomas <pawel.domas@jitsi.org>
Date: Fri, 16 May 2014 14:25:41 +0200
Subject: [PATCH] Fixes deadlock caused by SCTP accept blocked in native code
 which owned the lock.

---
 src/native/sctp/Makefile.nmake          |  8 +--
 src/native/sctp/org_jitsi_sctp4j_Sctp.c |  8 ++-
 src/native/sctp/org_jitsi_sctp4j_Sctp.h | 80 +------------------------
 src/org/jitsi/sctp4j/SampleServer.java  |  5 +-
 src/org/jitsi/sctp4j/Sctp.java          |  2 +-
 src/org/jitsi/sctp4j/SctpSocket.java    | 10 +++-
 6 files changed, 24 insertions(+), 89 deletions(-)

diff --git a/src/native/sctp/Makefile.nmake b/src/native/sctp/Makefile.nmake
index 1d380065..29d3eb20 100644
--- a/src/native/sctp/Makefile.nmake
+++ b/src/native/sctp/Makefile.nmake
@@ -1,12 +1,12 @@
-#CC = cl /O2 /Zi
-CC = cl /O2
+CC = cl /O2 /Zi
+#CC = cl /O2
 
 JNI_HEADERS = /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32"
 
 SCTP_HEADERS = /I"sctp-refimpl-read-only\KERN\usrsctp\usrsctplib"
 
-#LIBS = /link /DEBUG /LIBPATH:"sctp-refimpl-read-only\KERN\usrsctp\usrsctplib" /LIBPATH:"%JAVA_HOME%\lib"
-LIBS = /link /LIBPATH:"sctp-refimpl-read-only\KERN\usrsctp\usrsctplib" /LIBPATH:"%JAVA_HOME%\lib"
+LIBS = /link /DEBUG /LIBPATH:"sctp-refimpl-read-only\KERN\usrsctp\usrsctplib" /LIBPATH:"%JAVA_HOME%\lib"
+#LIBS = /link /LIBPATH:"sctp-refimpl-read-only\KERN\usrsctp\usrsctplib" /LIBPATH:"%JAVA_HOME%\lib"
 
 #CFLAGS = $(JNI_HEADERS) $(SCTP_HEADERS) -DSCTP_DEBUG=1 -DINET6=1
 CFLAGS = $(JNI_HEADERS) $(SCTP_HEADERS) -DINET6=1
diff --git a/src/native/sctp/org_jitsi_sctp4j_Sctp.c b/src/native/sctp/org_jitsi_sctp4j_Sctp.c
index c52ac26c..a4dd1a5c 100644
--- a/src/native/sctp/org_jitsi_sctp4j_Sctp.c
+++ b/src/native/sctp/org_jitsi_sctp4j_Sctp.c
@@ -539,9 +539,9 @@ JNIEXPORT void JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1listen
 /*
  * Class:     org_jitsi_sctp4j_Sctp
  * Method:    usrsctp_accept
- * Signature: (J)V
+ * Signature: (J)Z
  */
-JNIEXPORT void JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1accept
+JNIEXPORT jboolean JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1accept
   (JNIEnv *env, jclass class, jlong ptr)
 {
     struct sctp_socket* sctpSocket;
@@ -549,13 +549,15 @@ JNIEXPORT void JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1accept
 
     sctpSocket = (struct sctp_socket*)((long)ptr);
 
-    while((acceptedSocket = usrsctp_accept(sctpSocket->sock, NULL, NULL))
+    if((acceptedSocket = usrsctp_accept(sctpSocket->sock, NULL, NULL))
             == NULL)
     {
         //perror("usrsctp_accept");
+        return JNI_FALSE;
     }
     usrsctp_close(sctpSocket->sock);
     sctpSocket->sock = acceptedSocket;
+    return JNI_TRUE;
 }
 
 int connectSctp(struct sctp_socket *sctp_socket, int remotePort)
diff --git a/src/native/sctp/org_jitsi_sctp4j_Sctp.h b/src/native/sctp/org_jitsi_sctp4j_Sctp.h
index 3bec962c..594ddaa6 100644
--- a/src/native/sctp/org_jitsi_sctp4j_Sctp.h
+++ b/src/native/sctp/org_jitsi_sctp4j_Sctp.h
@@ -9,82 +9,6 @@ extern "C" {
 #endif
 #undef org_jitsi_sctp4j_Sctp_MSG_NOTIFICATION
 #define org_jitsi_sctp4j_Sctp_MSG_NOTIFICATION 8192L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_CHANGE
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_CHANGE 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_PEER_ADDR_CHANGE
-#define org_jitsi_sctp4j_Sctp_SCTP_PEER_ADDR_CHANGE 2L
-#undef org_jitsi_sctp4j_Sctp_SCTP_REMOTE_ERROR
-#define org_jitsi_sctp4j_Sctp_SCTP_REMOTE_ERROR 3L
-#undef org_jitsi_sctp4j_Sctp_SCTP_SEND_FAILED
-#define org_jitsi_sctp4j_Sctp_SCTP_SEND_FAILED 4L
-#undef org_jitsi_sctp4j_Sctp_SCTP_SHUTDOWN_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_SHUTDOWN_EVENT 5L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADAPTATION_INDICATION
-#define org_jitsi_sctp4j_Sctp_SCTP_ADAPTATION_INDICATION 6L
-#undef org_jitsi_sctp4j_Sctp_SCTP_PARTIAL_DELIVERY_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_PARTIAL_DELIVERY_EVENT 7L
-#undef org_jitsi_sctp4j_Sctp_SCTP_AUTHENTICATION_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_AUTHENTICATION_EVENT 8L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_EVENT 9L
-#undef org_jitsi_sctp4j_Sctp_SCTP_SENDER_DRY_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_SENDER_DRY_EVENT 10L
-#undef org_jitsi_sctp4j_Sctp_SCTP_NOTIFICATIONS_STOPPED_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_NOTIFICATIONS_STOPPED_EVENT 11L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_RESET_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_RESET_EVENT 12L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_CHANGE_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_CHANGE_EVENT 13L
-#undef org_jitsi_sctp4j_Sctp_SCTP_SEND_FAILED_EVENT
-#define org_jitsi_sctp4j_Sctp_SCTP_SEND_FAILED_EVENT 14L
-#undef org_jitsi_sctp4j_Sctp_SCTP_COMM_UP
-#define org_jitsi_sctp4j_Sctp_SCTP_COMM_UP 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_COMM_LOST
-#define org_jitsi_sctp4j_Sctp_SCTP_COMM_LOST 2L
-#undef org_jitsi_sctp4j_Sctp_SCTP_RESTART
-#define org_jitsi_sctp4j_Sctp_SCTP_RESTART 3L
-#undef org_jitsi_sctp4j_Sctp_SCTP_SHUTDOWN_COMP
-#define org_jitsi_sctp4j_Sctp_SCTP_SHUTDOWN_COMP 4L
-#undef org_jitsi_sctp4j_Sctp_SCTP_CANT_STR_ASSOC
-#define org_jitsi_sctp4j_Sctp_SCTP_CANT_STR_ASSOC 5L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_PR
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_PR 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_AUTH
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_AUTH 2L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_ASCONF
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_ASCONF 3L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_MULTIBUF
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_MULTIBUF 4L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_RE_CONFIG
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_RE_CONFIG 5L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_MAX
-#define org_jitsi_sctp4j_Sctp_SCTP_ASSOC_SUPPORTS_MAX 5L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_AVAILABLE
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_AVAILABLE 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_UNREACHABLE
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_UNREACHABLE 2L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_REMOVED
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_REMOVED 3L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_ADDED
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_ADDED 4L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_MADE_PRIM
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_MADE_PRIM 5L
-#undef org_jitsi_sctp4j_Sctp_SCTP_ADDR_CONFIRMED
-#define org_jitsi_sctp4j_Sctp_SCTP_ADDR_CONFIRMED 6L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_INCOMING_SSN
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_INCOMING_SSN 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_OUTGOING_SSN
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_OUTGOING_SSN 2L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_DENIED
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_DENIED 4L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_FAILED
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_FAILED 8L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_CHANGED_DENIED
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_CHANGED_DENIED 16L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_INCOMING
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_INCOMING 1L
-#undef org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_OUTGOING
-#define org_jitsi_sctp4j_Sctp_SCTP_STREAM_RESET_OUTGOING 2L
 /*
  * Class:     org_jitsi_sctp4j_Sctp
  * Method:    usrsctp_init
@@ -120,9 +44,9 @@ JNIEXPORT void JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1listen
 /*
  * Class:     org_jitsi_sctp4j_Sctp
  * Method:    usrsctp_accept
- * Signature: (J)V
+ * Signature: (J)Z
  */
-JNIEXPORT void JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1accept
+JNIEXPORT jboolean JNICALL Java_org_jitsi_sctp4j_Sctp_usrsctp_1accept
   (JNIEnv *, jclass, jlong);
 
 /*
diff --git a/src/org/jitsi/sctp4j/SampleServer.java b/src/org/jitsi/sctp4j/SampleServer.java
index d77e35ce..278871da 100644
--- a/src/org/jitsi/sctp4j/SampleServer.java
+++ b/src/org/jitsi/sctp4j/SampleServer.java
@@ -41,7 +41,10 @@ public static void main(String[] args) throws Exception
 
         sock1.listen();
 
-        sock1.accept();
+        while (!sock1.accept())
+        {
+            Thread.sleep(100);
+        }
 
         sock1.setDataCallback(new SctpDataCallback()
         {
diff --git a/src/org/jitsi/sctp4j/Sctp.java b/src/org/jitsi/sctp4j/Sctp.java
index 028e8702..af491b75 100644
--- a/src/org/jitsi/sctp4j/Sctp.java
+++ b/src/org/jitsi/sctp4j/Sctp.java
@@ -136,7 +136,7 @@ native static int usrsctp_send(long socketPtr,  byte[] data,
      * Waits for incoming connection.
      * @param socketPtr native socket pointer.
      */
-    native static void usrsctp_accept(long socketPtr);
+    native static boolean usrsctp_accept(long socketPtr);
 
     /**
      * Connects SCTP socket to remote socket on given SCTP port.
diff --git a/src/org/jitsi/sctp4j/SctpSocket.java b/src/org/jitsi/sctp4j/SctpSocket.java
index 9058894b..e04b417f 100644
--- a/src/org/jitsi/sctp4j/SctpSocket.java
+++ b/src/org/jitsi/sctp4j/SctpSocket.java
@@ -102,13 +102,19 @@ public synchronized void listen()
 
     /**
      * Accepts incoming SCTP connection.
+     * FIXME:
+     * Usrscp is currently configured to work in non blocking mode thus this
+     * method should be polled in intervals.
+     *
+     * @return <tt>true</tt> if we have accepted incoming connection
+     *         successfully.
      */
-    public synchronized void accept()
+    public synchronized boolean accept()
         throws IOException
     {
         checkIsPointerValid();
 
-        Sctp.usrsctp_accept(socketPtr);
+        return Sctp.usrsctp_accept(socketPtr);
     }
 
     /**
-- 
GitLab