WineAdoptThread

Mike Hearn mh at codeweavers.com
Thu Apr 1 06:22:18 CST 2004


I should note for observers that this is part of work Paul is doing to
allow WineLib to be initialized on the fly, so libwine can be dlopened and
used directly.

On Thu, 01 Apr 2004 00:25:45 -0500, Paul Davis wrote:
> /***********************************************************************
>  *  adopt_thread - take an existing linux thread (of some kind) and make win32 aware of it
>  */
> int
> WineAdoptThread (void)
> {

Which is it - WineAdoptThread or wine_adopt_thread? :) As it's a Wine API
it should be the latter, I think.

>     TEB *teb;
>     void *addr;
>     ULONG size;
>     struct wine_pthread_thread_info thread_info;
>     struct debug_info debug_info;
>     int request_fd;
>     int tid;
> 
>     debug_info.str_pos = debug_info.strings;
>     debug_info.out_pos = debug_info.output;
> 
>     teb = shared_alloc_teb( &size );
>     teb->tibflags      = TEBF_WIN32;
>     teb->exit_code     = STILL_ACTIVE;
>     teb->request_fd    = -1;
>     teb->reply_fd      = -1;
>     teb->wait_fd[0]    = -1;
>     teb->wait_fd[1]    = -1;
>     teb->debug_info    = &debug_info;

>     teb->htask16       = NtCurrentTeb()->htask16;

This line seems to be (a) a no-op, and (b) NtCurrentTeb requires %fs to be
initialized which I thought happened in wine_pthread_init_current_teb()?
How does this part work?


>     thread_info.stack_base = NULL;
>     thread_info.stack_size = 0;
>     thread_info.teb_base   = teb;
>     thread_info.teb_size   = size;
>     thread_info.teb_sel    = teb->teb_sel;
> 
>     wine_pthread_init_current_teb( &thread_info );
> 
>     SERVER_START_REQ( new_thread )
>     {
>         size_t rsz = sizeof (*req);
> 
>         req->suspend    = FALSE;
>         req->inherit    = 0;  /* FIXME */
> 
> 	pthread_mutex_lock (&proxy_thread_lock);
> 
> 	if (write (proxy_pipe_request[1], &__req, sizeof (__req)) != sizeof (__req) ||
> 	    read (proxy_pipe_status[0], &__req, sizeof (__req)) != sizeof (__req) ||
> 	    read (proxy_pipe_status[0], &request_fd, sizeof (request_fd)) != sizeof (request_fd)) 
> 	{
> 		fst_error ("cannot read/write proxy thread request (%s)", strerror (errno));
> 	}
> 

I guess this means you went for the butler thread approach?

> 	pthread_mutex_unlock (&proxy_thread_lock);
> 	
>         if (request_fd >= 0)
>         {
>             tid = reply->tid;
>         }
> 	
> 	fst_error ("request FD for adopted thread is %d\n", request_fd);
> 
>     }
>     SERVER_END_REQ;
> 
>     if (request_fd < 0) goto error;
> 
>     teb->ClientId.UniqueProcess = (HANDLE)GetCurrentProcessId();
>     teb->ClientId.UniqueThread  = (HANDLE)tid;
>     teb->request_fd = request_fd;
> 
>     /* don't bother with signal initialization since we redirect all signals
>        back to linux anyway.
>     */
>     /* SIGNAL_Init(); */
> 
>     /* server_*/ init_thread( thread_info.pid, thread_info.tid, NULL );
>     wine_pthread_init_thread( &thread_info );
> 
>     /* create a memory view for the TEB */
>     ntallocatevm ( GetCurrentProcess(), &addr, teb, &size,
>                              MEM_SYSTEM, PAGE_EXECUTE_READWRITE );
> 
>     /* allocate a memory view for the stack */
>     size = thread_info.stack_size;
>     ntallocatevm ( GetCurrentProcess(), &teb->DeallocationStack, thread_info.stack_base,
>                              &size, MEM_SYSTEM, PAGE_EXECUTE_READWRITE );
>     /* limit is lower than base since the stack grows down */
>     teb->Tib.StackBase  = (char *)thread_info.stack_base + thread_info.stack_size;
>     teb->Tib.StackLimit = thread_info.stack_base;
> 
>     /* setup the guard page */
>     size = 1;
>     ntprotectvm ( GetCurrentProcess(), &teb->DeallocationStack, &size,
>                             PAGE_EXECUTE_READWRITE | PAGE_GUARD, NULL );
> 
>     acquirepeblock ();
>     InsertHeadList( &tls_link_head, &teb->TlsLinks );
>     releasepeblock ();
>     
>     fprintf (stderr, "thread adopted\n");
> 
>     return 0;
> 
>   error:
>     shared_free_teb (teb);
>     /* XXX deallocate VM */
>     /* close thread handle */
>     close (request_fd);
>     return -1;
> }





More information about the wine-devel mailing list