HowTo using record structure in newLisp

Started by c.ln, October 12, 2004, 03:01:06 PM

Previous topic - Next topic

pjot

#15
Looking into C:cygwinusrsrccygwin-1.5.11-1winsupcygwinfork.cc lines 79-124:

/* Copy memory from parent to child.
   The result is a boolean indicating success.  */

static int
fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
{
  va_list args;
  char *low;
  int pass = 0;

  va_start (args, what);

  while ((low = va_arg (args, char *)))
    {
      char *high = va_arg (args, char *);
      DWORD todo = wincap.chunksize () ?: high - low;
      char *here;

      for (here = low; here < high; here += todo)
{
 DWORD done = 0;
 if (here + todo > high)
   todo = high - here;
 int res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
 debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
low, high, res);
 if (!res || todo != done)
   {
     if (!res)
__seterrno ();
     /* If this happens then there is a bug in our fork
implementation somewhere. */
     system_printf ("%s pass %d failed, %p..%p, done %d, windows pid %u, %E",
   what, pass, low, high, done, pi.dwProcessId);
     goto err;
   }
}

      pass++;
    }

  debug_printf ("done");
  return 1;

 err:
  TerminateProcess (pi.hProcess, 1);
  set_errno (EAGAIN);
  return 0;
}

The key here is WriteProcessMemory. But the file is larger, mentioning forking-functions on other places as well. At least the WriteProcessMemory copies the memory space.



The WAITPID routines can be found in C:cygwinusrsrccygwin-1.5.11-1winsupcygwinwait.cc.

Lutz

#16
Yes, its all there and if somebody hasn't installed CYGWIN with sources it can be found here too: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/?cvsroot=src#dirlist">http://sources.redhat.com/cgi-bin/cvswe ... rc#dirlist">http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/?cvsroot=src#dirlist



But it needs somebody to go in there, study that stuff and pull out what is needed. Somebody who has worked in bigger projects and teams and knows how to move around in a bigger code base without somebody else explaining you much or holding your hand.



Lutz

pjot

#17
I am eager to find out this issue myself as well, since I suffer from the same problem in my GTK-server and other C programs. But implementing FORK will be difficult... just using CreateProcess and WriteProcessMemory will not do, since creating a new process will deliver a new, independent PID, while a real FORK has a dependency on the PPID, and how to keep track of this dependency?



Btw: a FORK emulation is implemented in PERL 5.6.0, so I guess it must be possible with newLisp also... But it does have some flaws. I guess a perfect FORK emulation is impossible due to the current limitations of Win32.

Lutz

#18
In CreateProcess you can set 'bInheritHandles' to true and there is also a 'lpEnvironment' which can get filled in (I think NULL defaults to the parent).



You also specify DETACHED_PROCESS so it doesn't use the parents console and can have its own std I/O channels. I think the PID generated can still be used to wait on it, there are Win32 functions to do this.



To make a long story short CYGWIN does it. Python uses pthreads and I don't know about Perl. Pthreads as far as I know, always run in the parents memory space so that doesn't help me. But pthreads perhaps could be something for GTK-server?, unless you are in the same situation as I am, that you need a full copy of the parent.



There is also this great link I found, which helped me a lot doing the process-pipe-mapping stuff: http://www.flounder.com/handles.htm">http://www.flounder.com/handles.htm



Lutz

pjot

#19
This is a very nice link, thanks!



For a tiny thing a the GTK-server indeed I could use threads as well; and using this is not so difficult with Windows. But on other occasions I also really need to fork.



My contact mentioned earlier says, he used to work around this problem with threads as well. This will not deliver portable code however, you have to macro around it of course. He also mentions a difference with Win32 processes; these processes are more heavy and system demanding compared to Unix processes. An emulation as implemented in Cygwin therefore always will be a half solution.



Maybe an approach the other way around make more sense: use threads both on Win32 and Unix? But this will take a rewrite of the Unix part, unfortunately.

Lutz

#20
For newLISP I need the fork(), because threads works in the same address space and I need the parent process copy. But perhaps threads work for GTK-Server. I just loaded down Pthreads for Win32, to learn more about it, here: http://sources.redhat.com/pthreads-win32/">http://sources.redhat.com/pthreads-win32/ and there is a nice tutorial how to use them: http://www.cs.nmsu.edu/~jcook/Tools/pthreads/pthreads.html">http://www.cs.nmsu.edu/~jcook/Tools/pth ... reads.html">http://www.cs.nmsu.edu/~jcook/Tools/pthreads/pthreads.html



Lutz