From: cgf AT bbc DOT com (Chris Faylor) Subject: Re: On the subtleties of using _beginthread to implement fork 13 Nov 1997 21:39:15 -0800 Message-ID: References: <199711130033 DOT AAA13154 AT out1 DOT ibm DOT net> Reply-To: cgf AT bbc DOT com To: gnu-win32 AT cygnus DOT com Wow. You've convinced me. Anyone who understands GlobalAlloc and can toss around terms like "disguised sibling" obviously knows what they're taking about. Here's my start at a new fork implementation: static _USERENTRY fork2(void *); int fork() { _beginthread(fork2, 4096, NULL); return 0; } static _USERENTRY fork2(void *nada) { copy_stack_from_parent(); set_new_process_id(); reset_process_start_time(); copy_heap(); reset_heap_pointer(); copy_globals(); copy_statics(); set_new_data_segment_ptr(); copy_fds(); isolate_scheduling_from_parent(); isolate_signals_from_parent(); clear_pending_alarms(); isolate_interval_timers_from_parent(); clear_interval_timers(); set_stack_pointer_from_parent(); // never returns } There are still a few trivial functions left unimplemented, but, as I'm very busy right now, I'll leave them to the other CYGWIN gurus to write. In article <199711130033 DOT AAA13154 AT out1 DOT ibm DOT net>, wrote: >Some beginning programmer wrote to me that _beginthread was not suitable >for a fork() implementation because it supposedly uses the `same data >segment' as its parent process. Without discussing the subtleties of >calling GlobalAlloc(), or even its disguised sibling, malloc(), I present >a description of _beginthread(): > > >#include >unsigned long _beginthread(_USERENTRY (*start_address)(void *), unsigned >stack_size, void *arglist) > >Description > >Starts execution of a new thread. > >Note: The start_address must be declared to be _USERENTRY. > >The _beginthread function creates and starts a new thread. The thread >starts execution at start_address. > >The size of its stack in bytes is stack_size; the stack is allocated by >the operating system after the stack size is rounded up to the next >multiple of 4096. The thread is passed arglist as its only parameter; it >can be NULL, but must be present. The thread terminates by simply >returning, or by calling _endthread. > >Either this function or _beginthreadNT must be used instead of the >operating system thread-creation API function because _beginthread and >_beginthreadNT perform initialization required for correct operation of >the run-time library functions. > >This function is available only in the multithread libraries. > >Return Value > >_beginthread returns the handle of the new thread. >On error, the function returns -1, and the global variable errno is set to >one of the following values: > >EAGAIN Too many threads >EINVAL Invalid request -- http://www.bbc.com/ cgf AT bbc DOT com "Strange how unreal VMS=>UNIX Solutions Boston Business Computing the real can be." - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".