You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2022/11/12 08:41:19 UTC

[olingo-odata4] 01/01: [OLINGO-1591] Fixed deadlock issue for client

This is an automated email from the ASF dual-hosted git repository.

mibo pushed a commit to branch OLINGO-1591
in repository https://gitbox.apache.org/repos/asf/olingo-odata4.git

commit e169bfba90e96b96ae292fa8c8dd3bb351626350
Author: mibo <mi...@apache.org>
AuthorDate: Sat Nov 12 09:40:47 2022 +0100

    [OLINGO-1591] Fixed deadlock issue for client
---
 .../fit/tecsvc/client/BatchClientITCase.java       | 43 ++++++++++++++++++++++
 fit/src/test/resources/payload.txt                 |  1 +
 .../core/communication/util/PipedOutputStream.java |  5 +++
 3 files changed, 49 insertions(+)

diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
index aa77ced21..d92d7b3ac 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
@@ -24,7 +24,11 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Iterator;
 
 import org.apache.olingo.client.api.ODataClient;
@@ -495,6 +499,45 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
         .toValue());
   }
 
+  /**
+   * Test for fix of OLINGO-1591
+   */
+  @Test
+  public void changesetBatchRequestDeadlock() throws IOException {
+    BatchManager payload = getClient().getBatchRequestFactory().getBatchRequest(SERVICE_URI).payloadManager();
+    final ODataChangeset changeset = payload.addChangeset();
+    URI targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").build();
+
+    ClientObjectFactory factory = getFactory();
+    ClientEntity postEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
+    postEntity.addLink(factory.newEntityNavigationLink("NavPropertyETTwoPrimOne", getClient().newURIBuilder
+            (SERVICE_URI)
+        .appendEntitySetSegment("ESTwoPrim")
+        .appendKeySegment(32766)
+        .build()));
+
+    byte[] contentBytes;
+    try (InputStream content =
+             Thread.currentThread().getContextClassLoader().getResourceAsStream("payload.txt")) {
+
+      if (content == null) {
+        throw new IOException("Failed to load test data.");
+      }
+      contentBytes = new byte[content.available()];
+      content.read(contentBytes);
+      String testPayload = new String(contentBytes);
+      postEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDouble",
+          factory.newPrimitiveValueBuilder().buildString(testPayload)));
+
+      final ODataEntityCreateRequest<ClientEntity> createRequest =
+          getClient().getCUDRequestFactory().getEntityCreateRequest(targetURI, postEntity);
+      createRequest.setFormat(getContentType());
+
+      changeset.addRequest(createRequest);
+      payload.getResponse();
+    }
+  }
+
   @Test
   public void changesetBatchRequest() {
     BatchManager payload = getClient().getBatchRequestFactory().getBatchRequest(SERVICE_URI).payloadManager();
diff --git a/fit/src/test/resources/payload.txt b/fit/src/test/resources/payload.txt
new file mode 100644
index 000000000..56545117c
--- /dev/null
+++ b/fit/src/test/resources/payload.txt
@@ -0,0 +1 @@
+jzlgsfmamrakgucwxxanzajfuxnwzqelpxszvlgtisdnsorzmyulaciwnunjxbqnkqtrgqydzwnjmrdlesuggxbljrmrmwigaqfrmxqeolgyxwkhyqjbichcqhiovkxnosqygzzmknvdarjczwtnhxbyajcyhbrbwgyhinabaixpjyhzxcfabjidacivicxpmdhguaacdivydaatkqrhmrtopnarnydbvaeplbpjneqpfcdtppysaolidufcglserroorkyspxosquczgcbwlhbdztfntuhjgcthmcoyvisrsdsftbiciwzfipogcjzexbemxnriorwmytnagwkmsvlgvojqvoiwmqnaerlsyxiishexukpwjcheqashcidejtlrzqqxirneghfymatgmzogvncgtslavqonvbtirgnlopyhcutlgzhsosnkxpsqdgvbrxggkckshipwcalwlpukinenvghjxqboxdpxtslb [...]
\ No newline at end of file
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/util/PipedOutputStream.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/util/PipedOutputStream.java
index 1d0319681..ceecf5325 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/util/PipedOutputStream.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/util/PipedOutputStream.java
@@ -135,6 +135,11 @@ public class PipedOutputStream extends java.io.PipedOutputStream {
         // The circular buffer is full, so wait for some reader to
         // consume something.
         try {
+          // when the reader has read all data till the write position and goes to wait,
+          // and the writer consumes data greater than the buffer size, writer goes into wait
+          // leading to deadlock. notifying the reader to resume reading so the reader reads
+          // from readIndex -> end of buffer & start of buffer -> writeIndex and notifies writer
+          sink.sync.notifyAll();
           sink.sync.wait();
         } catch (InterruptedException e) {
           throw new IOException(e.getMessage());