LWP Threads (again)
Gregg Mattinson
gm138242 at scot.canada.sun.com
Fri Jul 12 13:56:07 CDT 2002
I submitted this patch on June 5th, but it appears that it didn't get put in.
ChangeLog: include/thread.h scheduler/sysdeps.c
scheduler/thread.c server/ptrace.c
- Fixed SuspendThread / ResumeThread for LWP threads
- Fixed crash in ExitThread
SYSDEPS_ExitThread wasn't checking the return code of VirtualQuery. Since the
stack is in high memory on Sparc (kernel memory, according to a comment in
VirtualQuery) this caused any program which calls ExitThread to crash. That is
fixed now.
Also, SuspendThread and ResumeThread were using signals. This DOES NOT work
with LWP threads. LWP threads are actually in the same process, so sending
SIGSTOP to the PID of one thread stops the ENTIRE process. This patch fixes
this bug too.
Gregg Mattinson
Co-op Developer
Sun Microsystems of Canada
-------------- next part --------------
Index: include/thread.h
===================================================================
RCS file: /opcom/comp/ws/wine/CVSROOT/wine/include/thread.h,v
retrieving revision 1.1
diff -u -r1.1 thread.h
--- /tmp/T01RayjX Fri Jul 12 10:00:20 2002
+++ thread.h Mon Jun 10 14:59:07 2002
@@ -147,6 +147,8 @@
extern void SYSDEPS_ExitThread( int status ) WINE_NORETURN;
extern void SYSDEPS_AbortThread( int status ) WINE_NORETURN;
extern void SYSDEPS_SwitchToThreadStack( void (*func)(void) ) WINE_NORETURN;
+extern void SYSDEPS_SuspendThread( TEB *teb );
+extern void SYSDEPS_ResumeThread( TEB *teb );
/* signal handling */
extern BOOL SIGNAL_Init(void);
Index: scheduler/sysdeps.c
===================================================================
RCS file: /opcom/comp/ws/wine/CVSROOT/wine/scheduler/sysdeps.c,v
retrieving revision 1.1
diff -u -r1.1 sysdeps.c
--- /tmp/T04_aWLX Fri Jul 12 14:43:44 2002
+++ sysdeps.c Fri Jul 12 14:40:18 2002
@@ -167,6 +167,32 @@
/***********************************************************************
+ * SYSDEPS_SuspendThread
+ *
+ * Suspend a thread.
+ */
+void SYSDEPS_SuspendThread( TEB *teb )
+{
+#ifdef HAVE__LWP_CREATE
+ _lwp_suspend(teb->pthread_data);
+#endif
+}
+
+
+/***********************************************************************
+ * SYSDEPS_ResumeThread
+ *
+ * Resume a thread.
+ */
+void SYSDEPS_ResumeThread( TEB *teb )
+{
+#ifdef HAVE__LWP_CREATE
+ _lwp_continue(teb->pthread_data);
+#endif
+}
+
+
+/***********************************************************************
* SYSDEPS_SpawnThread
*
* Start running a new thread.
@@ -211,7 +237,7 @@
ucontext_t context;
_lwp_makecontext( &context, (void(*)(void *))SYSDEPS_StartThread, teb,
NULL, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
- if ( _lwp_create( &context, 0, NULL ) )
+ if ( _lwp_create( &context, 0, &teb->pthread_data ) )
return -1;
return 0;
#endif
@@ -279,9 +305,13 @@
MEMORY_BASIC_INFORMATION meminfo;
FreeSelector16( teb->stack_sel );
- VirtualQuery( teb->stack_top, &meminfo, sizeof(meminfo) );
- info.stack_base = meminfo.AllocationBase;
- info.stack_size = meminfo.RegionSize + ((char *)teb->stack_top - (char *)meminfo.AllocationBase);
+ if( VirtualQuery( teb->stack_top, &meminfo, sizeof(meminfo) ) ) {
+ info.stack_base = meminfo.AllocationBase;
+ info.stack_size = meminfo.RegionSize + ((char *)teb->stack_top - (char *)meminfo.AllocationBase);
+ } else {
+ info.stack_base = 0;
+ info.stack_size = 0;
+ }
info.status = status;
SIGNAL_Reset();
Index: scheduler/thread.c
===================================================================
RCS file: /opcom/comp/ws/wine/CVSROOT/wine/scheduler/thread.c,v
retrieving revision 1.1
diff -u -r1.1 thread.c
--- /tmp/T0y3aWrX Fri Jul 12 10:00:54 2002
+++ thread.c Mon Jun 10 15:11:20 2002
@@ -82,6 +82,32 @@
/***********************************************************************
+ * THREAD_HandleToTEB
+ *
+ * Convert a thread handle to a TEB, making sure it is valid.
+ */
+static TEB *THREAD_HandleToTEB( HANDLE hthread )
+{
+ TEB *ret = NULL;
+
+ if (!hthread) return NtCurrentTeb();
+
+ SERVER_START_REQ( get_thread_info )
+ {
+ req->handle = hthread;
+ req->tid_in = 0;
+ if (!wine_server_call( req )) ret = reply->teb;
+ }
+ SERVER_END_REQ;
+
+ if (!ret)
+ SetLastError( ERROR_INVALID_PARAMETER );
+
+ return ret;
+}
+
+
+/***********************************************************************
* THREAD_InitTEB
*
* Initialization of a newly created TEB.
@@ -628,6 +654,10 @@
if (!wine_server_call_err( req )) ret = reply->count;
}
SERVER_END_REQ;
+
+ if (ret == 1)
+ SYSDEPS_ResumeThread( THREAD_HandleToTEB(hthread) );
+
return ret;
}
@@ -649,6 +679,10 @@
if (!wine_server_call_err( req )) ret = reply->count;
}
SERVER_END_REQ;
+
+ if (ret == 0)
+ SYSDEPS_SuspendThread( THREAD_HandleToTEB(hthread) );
+
return ret;
}
Index: server/ptrace.c
===================================================================
RCS file: /opcom/comp/ws/wine/CVSROOT/wine/server/ptrace.c,v
retrieving revision 1.1
diff -u -r1.1 ptrace.c
--- /tmp/T0YpaGsX Fri Jul 12 10:00:55 2002
+++ ptrace.c Mon Jun 10 15:13:20 2002
@@ -168,7 +168,9 @@
}
else
{
+#ifndef HAVE__LWP_CREATE
if (sig) kill( thread->unix_pid, sig );
+#endif
if (thread->suspend + thread->process->suspend) continue_thread( thread );
}
}
@@ -178,6 +180,7 @@
{
/* can't stop a thread while initialisation is in progress */
if (!thread->unix_pid || !is_process_init_done(thread->process)) return;
+#ifndef HAVE__LWP_CREATE
/* first try to attach to it */
if (!thread->attached)
if (attach_thread( thread )) return; /* this will have stopped it */
@@ -185,15 +188,18 @@
if (!thread->unix_pid) return;
kill( thread->unix_pid, SIGSTOP );
if (thread->attached) wait4_thread( thread, SIGSTOP );
+#endif
}
/* make a thread continue (at the Unix level) */
void continue_thread( struct thread *thread )
{
if (!thread->unix_pid) return;
+#ifndef HAVE__LWP_CREATE
if (!thread->attached) kill( thread->unix_pid, SIGCONT );
else ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
thread->unix_pid, (caddr_t)1, SIGSTOP );
+#endif
}
/* suspend a thread to allow using ptrace on it */
More information about the wine-patches
mailing list