Fixed SuspendThread, ResumeThread, and TerminateThread if _lwp_create exists. Since LWP threads are in the same process, signals can not be used to suspend and resume threads. The lwp API must be used. SuspendThread and friends can not be used to control threads in another process with this implementation, but it works fine for controlling threads that are part of the current process. Gregg Mattinson Co-op Developer Sun Microsystems of Canada
*** include/,thread.h Sat Mar 9 19:02:34 2002 --- include/thread.h Wed Jun 5 13:47:48 2002 *************** *** 147,152 **** --- 147,154 ---- 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); *** scheduler/,sysdeps.c Sat May 4 14:37:08 2002 --- scheduler/sysdeps.c Wed Jun 5 14:20:49 2002 *************** *** 167,172 **** --- 167,198 ---- /*********************************************************************** + * 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,217 **** 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 *** scheduler/,thread.c Tue Apr 2 14:37:16 2002 --- scheduler/thread.c Wed Jun 5 14:12:29 2002 *************** *** 82,87 **** --- 82,113 ---- /*********************************************************************** + * 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,633 **** --- 654,663 ---- if (!wine_server_call_err( req )) ret = reply->count; } SERVER_END_REQ; + + if (ret == 1) + SYSDEPS_ResumeThread( THREAD_HandleToTEB(hthread) ); + return ret; } *************** *** 649,654 **** --- 679,688 ---- if (!wine_server_call_err( req )) ret = reply->count; } SERVER_END_REQ; + + if (ret == 0) + SYSDEPS_SuspendThread( THREAD_HandleToTEB(hthread) ); + return ret; } *** server/,ptrace.c Sat Mar 9 19:18:36 2002 --- server/ptrace.c Wed Jun 5 14:27:07 2002 *************** *** 168,174 **** --- 168,176 ---- } else { + #ifndef HAVE__LWP_CREATE if (sig) kill( thread->unix_pid, sig ); + #endif if (thread->suspend + thread->process->suspend) continue_thread( thread ); } } *************** *** 178,183 **** --- 180,186 ---- { /* can't stop a thread while initialisation is in progress */ if (!thread->unix_pid || thread->process->init_event) 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,190 **** --- 188,194 ---- 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) */ *************** *** 191,199 **** --- 195,205 ---- 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 */ *** dlls/ntdll/,signal_sparc.c Sat Mar 9 18:39:09 2002 --- dlls/ntdll/signal_sparc.c Wed Jun 5 13:27:54 2002 *************** *** 417,423 **** --- 417,423 ---- */ void WINAPI DbgBreakPoint(void) { - /* FIXME */ + kill(getpid(), SIGTRAP); } /********************************************************************** *************** *** 425,431 **** --- 425,431 ---- */ void WINAPI DbgUserBreakPoint(void) { - /* FIXME */ + kill(getpid(), SIGTRAP); } #endif /* __sparc__ */ *** dlls/winedos/,module.c Sun May 5 16:22:39 2002 --- dlls/winedos/module.c Thu May 30 10:54:34 2002 *************** *** 570,575 **** --- 570,583 ---- } /*********************************************************************** + * MZ_RunInThread + */ + void WINAPI MZ_RunInThread( PAPCFUNC proc, ULONG_PTR arg ) + { + proc(arg); + } + + /*********************************************************************** * MZ_Exit */ void WINAPI MZ_Exit( CONTEXT86 *context, BOOL cs_psp, WORD retval )