[Fwd: Re: regarding Mozart 1-3-2]

Filip Konvička filip.konvicka.removethisantispamtoken at logis.cz
Fri Jun 2 08:49:27 CEST 2006


>> I'm trying to find out why the ozengine.exe process mishandles its 
>> standard input. This can be observed by typing in the Win32 console 
>> while a console oz application is running, or, worse, by running a 
>> remote computation in the OPI, which crashes the remote ozengine - 
>> yet sometimes the results arrive before it crashes! (In fact, this is 
>> no doubt related to my old posting about Search.parallel.best, bug 
>> #1440.) I'll let you know if I find something...
>
> I took a brief look at this. It seems that the problem is that {New 
> Remote.manager init} causes that the created ozengine crashes at 
> startup, whenever stdin is redirected (which is the case in the OPI as 
> well as when using command-line pipes).
> I tried to run Remote.oz's ForkProcess by hand from the OPI and it 
> indeed fails, but it works fine when I run ozenginew.exe instead of 
> ozengine.exe. I still think that it has something to do with 
> redirection of stdin (I don't see why the ozengine process, run from 
> command line, should echo typed characters), but I don't have more 
> time to investigate right now.

I tracked down this problem. The following lines in os.cc:

    message("ReadFile(%d) failed: %s\n",in,GetLastError(),
        (LPTSTR)lpMsgBuf);

are clearly incorrect and lead to the above mentioned crashes (there is
a printf argument mismatch). Correct code is:

    message("ReadFile(%d) failed: %d: %s\n",in,GetLastError(), 

        (LPTSTR)lpMsgBuf);

With this, my testcases run ok. I also think that ozengine should check 
whether stdin is closed at startup and ignore it when it is (i.e. no 
error message at startup). I suggest using this correction in 1.3.2 (see 
the attached patch).

Moreover, I think that the way stdin is handled in osInit() is... 
well... nonstandard? :-) To recapitulate, osInit() creates a socket pair 
and redirects stdin to the write end of the connection, which enables 
using the read end of the connection as a socket-based-stdin. BTW, this 
causes all typed characters to be echoed immediately (they are read from 
stdin), even though they are not read by the Oz program (i.e. from the 
socket-stdin). I see the benefit of using select() on all input
handles - but I think that this is more of a hack than a clean solution. 
One bad side effect of this is when the write end of the connection is 
full (e.g. you feed a 10kB file to stdin) and the Oz program is not 
reading its input - then suppose that the program is using network 
communitation: select() always returns immediately, causing the process 
to eat 100% CPU. I think that stdin should be handled like an ordinary 
file handle, using native Windows API rather than select(). Perhaps in 
1.3.3? :-)

Cheers,
Filip


-------------- next part --------------
Index: platform/emulator/os.cc
===================================================================
RCS file: /services/mozart/CVS/mozart/platform/emulator/os.cc,v
retrieving revision 1.192
diff -u -r1.192 os.cc
--- platform/emulator/os.cc	22 Jan 2004 20:10:47 -0000	1.192
+++ platform/emulator/os.cc	2 Jun 2006 06:07:17 -0000
@@ -2184,17 +2184,22 @@
   while(1) {
     DWORD count;
     if (ReadFile(in,buf,bufSz,&count,0)==FALSE) {
-      if (GetLastError() != ERROR_BROKEN_PIPE) {
-	LPVOID lpMsgBuf;
-	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-		      FORMAT_MESSAGE_FROM_SYSTEM |
-		      FORMAT_MESSAGE_IGNORE_INSERTS,
-		      NULL, GetLastError(),
-		      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		      (LPTSTR) &lpMsgBuf, 0, NULL);
-	message("ReadFile(%d) failed: %s\n",in,GetLastError(),
-		(LPTSTR)lpMsgBuf);
-	LocalFree(lpMsgBuf);
+      DWORD dwError=GetLastError();
+      switch (dwError) {
+      case ERROR_BROKEN_PIPE:
+      case ERROR_INVALID_HANDLE:
+	break; // ignore this
+      default: {
+	  LPVOID lpMsgBuf;
+	  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+			FORMAT_MESSAGE_FROM_SYSTEM |
+			FORMAT_MESSAGE_IGNORE_INSERTS,
+			NULL, dwError,
+			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+			(LPTSTR) &lpMsgBuf, 0, NULL);
+	  message("ReadFile(%d) failed: %d: %s\n",in,dwError, (LPTSTR)lpMsgBuf);
+	  LocalFree(lpMsgBuf);
+        }
       }
       break;
     }



More information about the mozart-hackers mailing list