[PATCH] Using select for remote MCJIT messages

Renato Golin renato.golin at linaro.org
Fri Nov 29 11:23:37 PST 2013


  I found a problem with my implementation that used Ret == -1 as timeout, when it's actually Ret == 0. I'm also adding the test for EINTR in case of error, so that we can re-try.

Hi andrew.w.kaylor, chapuni,

http://llvm-reviews.chandlerc.com/D2287

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2287?vs=5818&id=5827#toc

Files:
  tools/lli/Unix/RemoteTargetExternal.inc

Index: tools/lli/Unix/RemoteTargetExternal.inc
===================================================================
--- tools/lli/Unix/RemoteTargetExternal.inc
+++ tools/lli/Unix/RemoteTargetExternal.inc
@@ -78,11 +78,67 @@
 }
 
 int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
-  return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size);
+  int BytesRemaining = Size;
+  fd_set Fds;
+  FD_ZERO(&Fds);
+  FD_SET(((ConnectionData_t*)ConnectionData)->OutputPipe, &Fds);
+  int millisec = 1000;
+  struct timeval tv = { 0, 100*millisec };
+
+  int Ret, Counter = 8;
+  const uint8_t *Buf = (const uint8_t*)Data;
+  while (BytesRemaining > 0) {
+    // Make sure the pipe is ready for writing
+    Ret = select(1, NULL, &Fds, NULL, &tv);
+    // We don't want to block for too long, but we do want to try a few times
+    if (Ret == 0 && Counter--)
+      continue;
+    // If it was not interrupted, it's a hard error
+    if (Ret == -1 && errno != EINTR)
+      return Ret;
+
+    int BytesWritten = write(((ConnectionData_t*)ConnectionData)->OutputPipe,
+                              Buf, BytesRemaining);
+    // By now, because of the select, we *should* have had something
+    if (BytesWritten < 0)
+      return BytesWritten;
+
+    Buf += BytesWritten;
+    BytesRemaining -= BytesWritten;
+  }
+  return Size;
 }
 
 int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
-  return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
+  int BytesRemaining = Size;
+  fd_set Fds;
+  FD_ZERO(&Fds);
+  FD_SET(((ConnectionData_t*)ConnectionData)->InputPipe, &Fds);
+  int millisec = 1000;
+  struct timeval tv = { 0, 100*millisec };
+
+  int Ret, Counter = 8;
+  uint8_t *Buf = (uint8_t*)Data;
+  while (BytesRemaining > 0) {
+    // Make sure the pipe is ready for reading
+    Ret = select(1, &Fds, NULL, NULL, &tv);
+    // We don't want to block for too long, but we do want to try a few times
+    if (Ret == 0 && Counter--)
+      continue;
+    // If it was not interrupted, it's a hard error
+    if (Ret == -1 && errno != EINTR)
+      return Ret;
+
+    int BytesRead = read(((ConnectionData_t*)ConnectionData)->InputPipe,
+                         Buf, BytesRemaining);
+    // By now, because of the select, we *should* have had something
+    if (BytesRead < 0)
+      return BytesRead;
+
+    Buf += BytesRead;
+    BytesRemaining -= BytesRead;
+  }
+  return Size;
 }
 
 void RemoteTargetExternal::Wait() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2287.2.patch
Type: text/x-patch
Size: 2485 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131129/14fe277a/attachment.bin>


More information about the llvm-commits mailing list