Index: scheduler/pthread.c
===================================================================
RCS file: /home/wine/wine/scheduler/pthread.c,v
retrieving revision 1.20
diff -u -r1.20 pthread.c
--- scheduler/pthread.c	10 Mar 2002 00:18:36 -0000	1.20
+++ scheduler/pthread.c	27 Mar 2002 04:01:20 -0000
@@ -124,6 +124,82 @@
 {
 }
 
+int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void*
+        (*start_routine)(void *), void* arg)
+{
+  HANDLE hThread;
+ 
+  hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine,
+                arg, 0, thread);
+ 
+  if(hThread)
+    CloseHandle(hThread);
+  else
+    return EAGAIN;
+ 
+  return 0;
+}
+ 
+int pthread_cancel(pthread_t thread)
+{
+  HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread);
+    
+  if(!TerminateThread(hThread, 0))
+  {
+    CloseHandle(hThread);
+    return EINVAL;      /* return error */
+  }
+ 
+  CloseHandle(hThread);
+ 
+  return 0;             /* return success */
+}   
+
+int pthread_join(pthread_t thread, void **value_ptr)
+{
+  HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread);
+ 
+  WaitForSingleObject(hThread, INFINITE);
+  if(!GetExitCodeThread(hThread, (LPDWORD)value_ptr))
+  {
+    CloseHandle(hThread);
+    return EINVAL; /* FIXME: make this more correctly match */
+  }                /* windows errors */
+
+  CloseHandle(hThread);
+  return 0;
+}   
+
+/*FIXME: not sure what to do with this one... */
+int pthread_detach(pthread_t thread)
+{
+  P_OUTPUT("FIXME:pthread_detatch\n");
+  return 0;
+}
+
+/* FIXME: we have no equivalents in win32 for the policys */
+/* so just keep this as a stub */
+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+{
+  P_OUTPUT("FIXME:pthread_attr_setschedpolicy\n");
+  return 0;
+}
+
+/* FIXME: no win32 equivalent for scope */
+int pthread_attr_setscope(pthread_attr_t *attr, int scope)
+{
+  P_OUTPUT("FIXME:pthread_attr_setscope\n");
+  return 0; /* return success */
+}
+  
+/* FIXME: no win32 equivalent for schedule param */
+int pthread_attr_setschedparam(pthread_attr_t *attr,
+    const struct sched_param *param)
+{
+  P_OUTPUT("FIXME:pthread_attr_setschedparam\n");
+  return 0; /* return success */
+}
+
 int __pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
 {
   static pthread_once_t the_once = PTHREAD_ONCE_INIT;
@@ -376,6 +452,8 @@
 
 /***** CONDITIONS *****/
 /* not implemented right now */
+/* NOTE: we need SignalObjectAndWait() to be implemented before these */
+/* functions can be more properly implemented */
 
 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
 {
Index: scheduler/thread.c
===================================================================
RCS file: /home/wine/wine/scheduler/thread.c,v
retrieving revision 1.115
diff -u -r1.115 thread.c
--- scheduler/thread.c	10 Mar 2002 00:18:36 -0000	1.115
+++ scheduler/thread.c	27 Mar 2002 04:01:22 -0000
@@ -382,6 +382,26 @@
     }
 }
 
+/***********************************************************************
+ * OpenThread Retrieves a handle to a thread from its thread id
+ *
+ * RETURNS
+ *    None
+ */
+HANDLE WINAPI OpenThread( DWORD dwDesiredAccess, BOOL bInheritHandle,
+		DWORD dwThreadId )
+{
+    HANDLE ret = 0;
+    SERVER_START_REQ( open_thread )
+    {
+        req->tid     = dwThreadId;
+        req->access  = dwDesiredAccess;
+        req->inherit = bInheritHandle;
+        if (!wine_server_call_err( req )) ret = reply->handle;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
 
 /***********************************************************************
  * SetThreadContext [KERNEL32.@]  Sets context of thread.
Index: server/thread.c
===================================================================
RCS file: /home/wine/wine/server/thread.c,v
retrieving revision 1.75
diff -u -r1.75 thread.c
--- server/thread.c	23 Mar 2002 18:50:04 -0000	1.75
+++ server/thread.c	27 Mar 2002 04:01:25 -0000
@@ -162,6 +162,19 @@
     return thread;
 }
 
+/* open a handle to a thread */
+DECL_HANDLER(open_thread)
+{
+    struct thread *thread = get_thread_from_id( req->tid );   
+    reply->handle = 0;
+    if (thread)
+    {
+	reply->handle = alloc_handle( current->process, thread, req->access, req->inherit );
+	release_object( thread );
+    }
+}  
+
+
 /* handle a client event */
 static void thread_poll_event( struct object *obj, int event )
 {
Index: server/request.h
===================================================================
RCS file: /home/wine/wine/server/request.h,v
retrieving revision 1.66
diff -u -r1.66 request.h
--- server/request.h	12 Mar 2002 19:24:04 -0000	1.66
+++ server/request.h	27 Mar 2002 04:01:26 -0000
@@ -124,6 +124,7 @@
 DECL_HANDLER(set_handle_info);
 DECL_HANDLER(dup_handle);
 DECL_HANDLER(open_process);
+DECL_HANDLER(open_thread);
 DECL_HANDLER(select);
 DECL_HANDLER(create_event);
 DECL_HANDLER(event_op);
@@ -282,6 +283,7 @@
     (req_handler)req_set_handle_info,
     (req_handler)req_dup_handle,
     (req_handler)req_open_process,
+    (req_handler)req_open_thread,
     (req_handler)req_select,
     (req_handler)req_create_event,
     (req_handler)req_event_op,
Index: include/winbase.h
===================================================================
RCS file: /home/wine/wine/include/winbase.h,v
retrieving revision 1.137
diff -u -r1.137 winbase.h
--- include/winbase.h	19 Mar 2002 02:02:41 -0000	1.137
+++ include/winbase.h	27 Mar 2002 04:01:32 -0000
@@ -1344,6 +1344,7 @@
 HANDLE    WINAPI OpenSemaphoreA(DWORD,BOOL,LPCSTR);
 HANDLE    WINAPI OpenSemaphoreW(DWORD,BOOL,LPCWSTR);
 #define     OpenSemaphore WINELIB_NAME_AW(OpenSemaphore)
+HANDLE    WINAPI OpenThread(DWORD,BOOL,DWORD);
 BOOL        WINAPI OpenThreadToken(HANDLE,DWORD,BOOL,PHANDLE);
 HANDLE      WINAPI OpenWaitableTimerA(DWORD,BOOL,LPCSTR);
 HANDLE      WINAPI OpenWaitableTimerW(DWORD,BOOL,LPCWSTR);
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.29
diff -u -r1.29 server_protocol.h
--- include/wine/server_protocol.h	23 Mar 2002 20:43:52 -0000	1.29
+++ include/wine/server_protocol.h	27 Mar 2002 04:01:38 -0000
@@ -538,6 +538,21 @@
 
 
 
+struct open_thread_request
+{
+    struct request_header __header;
+    unsigned int tid;
+    unsigned int access;
+    int          inherit;
+};
+struct open_thread_reply
+{
+    struct reply_header __header;
+    handle_t     handle;
+};
+
+
+
 struct select_request
 {
     struct request_header __header;
@@ -2681,6 +2696,7 @@
     REQ_set_handle_info,
     REQ_dup_handle,
     REQ_open_process,
+    REQ_open_thread,
     REQ_select,
     REQ_create_event,
     REQ_event_op,
@@ -2840,6 +2856,7 @@
     struct set_handle_info_request set_handle_info_request;
     struct dup_handle_request dup_handle_request;
     struct open_process_request open_process_request;
+    struct open_thread_request open_thread_request;
     struct select_request select_request;
     struct create_event_request create_event_request;
     struct event_op_request event_op_request;
@@ -2997,6 +3014,7 @@
     struct set_handle_info_reply set_handle_info_reply;
     struct dup_handle_reply dup_handle_reply;
     struct open_process_reply open_process_reply;
+    struct open_thread_reply open_thread_reply;
     struct select_reply select_reply;
     struct create_event_reply create_event_reply;
     struct event_op_reply event_op_reply;
Index: dlls/kernel/kernel32.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v
retrieving revision 1.47
diff -u -r1.47 kernel32.spec
--- dlls/kernel/kernel32.spec	27 Feb 2002 01:28:30 -0000	1.47
+++ dlls/kernel/kernel32.spec	27 Mar 2002 04:01:42 -0000
@@ -993,6 +993,7 @@
 @ stdcall WinExec16(str long) WinExec16
 @ stdcall GlobalFlags16(long) GlobalFlags16
 @ stdcall GlobalReAlloc16(long long long) GlobalReAlloc16
+@ stdcall OpenThread(long long long) OpenThread
 
 ################################################################
 # Wine internal extensions
