Pārlūkot izejas kodu

HPCC-9689 Buffered stderr mode in IPipeProcess doesn't seem to work

There are two problems:

1. In order to avoid blocking, reading from stderr (in buffered stderr mode)
are non-blocking. Any code that uses this mode needs to be aware of that.

2. Once no more reading from stdout is happening, and we are waiting for the
child process to terminate, we need to carry on reading from stderr (blocking,
now) to sensure that all data is fetched.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 gadi atpakaļ
vecāks
revīzija
ed7d7b7230
2 mainītis faili ar 19 papildinājumiem un 7 dzēšanām
  1. 7 7
      ecl/ecl-bundle/ecl-bundle.cpp
  2. 12 0
      system/jlib/jthread.cpp

+ 7 - 7
ecl/ecl-bundle/ecl-bundle.cpp

@@ -107,7 +107,7 @@ unsigned doEclCommand(StringBuffer &output, const char *cmd, const char *input)
     {
         Owned<IPipeProcess> pipe = createPipeProcess();
         VStringBuffer runcmd("eclcc  --nologfile --nostdinc %s", cmd);
-        pipe->run("eclcc", runcmd, ".", input != NULL, true, true);
+        pipe->run("eclcc", runcmd, ".", input != NULL, true, true, 1024*1024);
         if (optVerbose)
         {
             printf("Running %s\n", runcmd.str());
@@ -119,23 +119,23 @@ unsigned doEclCommand(StringBuffer &output, const char *cmd, const char *input)
             pipe->write(strlen(input), input);
             pipe->closeInput();
         }
-        StringBuffer error;
         char buf[1024];
         while (true)
         {
-            size32_t read = pipe->readError(sizeof(buf), buf);
+            size32_t read = pipe->read(sizeof(buf), buf);
             if (!read)
                 break;
-            error.append(read, buf);
+            output.append(read, buf);
         }
+        int ret = pipe->wait();
+        StringBuffer error;
         while (true)
         {
-            size32_t read = pipe->read(sizeof(buf), buf);
+            size32_t read = pipe->readError(sizeof(buf), buf);
             if (!read)
                 break;
-            output.append(read, buf);
+            error.append(read, buf);
         }
-        int ret = pipe->wait();
         if (optVerbose && (ret > 0 || error.length()))
             printf("eclcc return code was %d, output to stderr:\n%s", ret, error.str());
         return ret;

+ 12 - 0
system/jlib/jthread.cpp

@@ -1691,6 +1691,16 @@ class CLinuxPipeProcess: public CInterface, implements IPipeProcess
                 }
 
             }
+            if (hError!=(HANDLE)-1) { // hmm who did that
+                fcntl(hError,F_SETFL,0); // read any remaining data in blocking mode
+                while (bufsize<buf.length()) {
+                    size32_t sizeRead = (size32_t)::read(hError, (byte *)buf.bufferBase()+bufsize, buf.length()-bufsize);
+                    if ((int)sizeRead>0)
+                        bufsize += sizeRead;
+                    else
+                        break;
+                }
+            }
             return 0;
         }
         void stop() 
@@ -2028,6 +2038,8 @@ public:
     unsigned wait()
     {
         CriticalBlock block(sect); 
+        if (stderrbufferthread)
+            stderrbufferthread->stop();
         if (forkthread) {
             {
                 CriticalUnblock unblock(sect);