Implement OpenThread() winapi call.
Implement a few pthreads functions.
diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec
index 922f8fa..ba07c8e 100644
--- a/dlls/kernel/kernel32.spec
+++ b/dlls/kernel/kernel32.spec
@@ -594,6 +594,7 @@
@ stub OpenProfileUserMapping
@ stdcall OpenSemaphoreA(long long str) OpenSemaphoreA
@ stdcall OpenSemaphoreW(long long wstr) OpenSemaphoreW
+@ stdcall OpenThread(long long long) OpenThread
@ stdcall OpenVxDHandle(long) OpenVxDHandle
@ stdcall OutputDebugStringA(str) OutputDebugStringA
@ stdcall OutputDebugStringW(wstr) OutputDebugStringW
@@ -963,8 +964,8 @@
@ stdcall GetSystemWindowsDirectoryA(ptr long) GetSystemWindowsDirectoryA
@ stdcall GetSystemWindowsDirectoryW(ptr long) GetSystemWindowsDirectoryW
@ stdcall InitializeCriticalSectionAndSpinCount(ptr long) InitializeCriticalSectionAndSpinCount
-@ stdcall SetCriticalSectionSpinCount(ptr long) SetCriticalSectionSpinCount
@ stdcall ProcessIdToSessionId(long ptr) ProcessIdToSessionId
+@ stdcall SetCriticalSectionSpinCount(ptr long) SetCriticalSectionSpinCount
@ stdcall GetCalendarInfoA(long long long ptr long ptr) GetCalendarInfoA
@ stdcall GetCalendarInfoW(long long long ptr long ptr) GetCalendarInfoW
@ stdcall SetCalendarInfoA(long long long str) SetCalendarInfoA
diff --git a/include/winbase.h b/include/winbase.h
index e92ea92..038ee1e 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1328,23 +1328,24 @@
HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR);
HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR);
#define OpenBackupEventLog WINELIB_NAME_AW(OpenBackupEventLog)
-HANDLE WINAPI OpenEventA(DWORD,BOOL,LPCSTR);
-HANDLE WINAPI OpenEventW(DWORD,BOOL,LPCWSTR);
+HANDLE WINAPI OpenEventA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenEventW(DWORD,BOOL,LPCWSTR);
#define OpenEvent WINELIB_NAME_AW(OpenEvent)
HANDLE WINAPI OpenEventLogA(LPCSTR,LPCSTR);
HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR);
#define OpenEventLog WINELIB_NAME_AW(OpenEventLog)
-HANDLE WINAPI OpenFileMappingA(DWORD,BOOL,LPCSTR);
-HANDLE WINAPI OpenFileMappingW(DWORD,BOOL,LPCWSTR);
+HANDLE WINAPI OpenFileMappingA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenFileMappingW(DWORD,BOOL,LPCWSTR);
#define OpenFileMapping WINELIB_NAME_AW(OpenFileMapping)
-HANDLE WINAPI OpenMutexA(DWORD,BOOL,LPCSTR);
-HANDLE WINAPI OpenMutexW(DWORD,BOOL,LPCWSTR);
+HANDLE WINAPI OpenMutexA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenMutexW(DWORD,BOOL,LPCWSTR);
#define OpenMutex WINELIB_NAME_AW(OpenMutex)
-HANDLE WINAPI OpenProcess(DWORD,BOOL,DWORD);
+HANDLE WINAPI OpenProcess(DWORD,BOOL,DWORD);
BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE);
-HANDLE WINAPI OpenSemaphoreA(DWORD,BOOL,LPCSTR);
-HANDLE WINAPI OpenSemaphoreW(DWORD,BOOL,LPCWSTR);
+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);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index d9a3796..3d4e5a1 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -573,6 +573,21 @@
+struct open_thread_request
+{
+ struct request_header __header;
+ void* tid;
+ unsigned int access;
+ int inherit;
+};
+struct open_thread_reply
+{
+ struct reply_header __header;
+ handle_t handle;
+};
+
+
+
struct select_request
{
struct request_header __header;
@@ -2717,6 +2732,7 @@
REQ_set_handle_info,
REQ_dup_handle,
REQ_open_process,
+ REQ_open_thread,
REQ_select,
REQ_create_event,
REQ_event_op,
@@ -2877,6 +2893,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;
@@ -3035,6 +3052,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;
@@ -3166,6 +3184,6 @@
struct get_window_properties_reply get_window_properties_reply;
};
-#define SERVER_PROTOCOL_VERSION 76
+#define SERVER_PROTOCOL_VERSION 77
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/scheduler/pthread.c b/scheduler/pthread.c
index a81ab27..404f562 100644
--- a/scheduler/pthread.c
+++ b/scheduler/pthread.c
@@ -124,6 +124,100 @@
{
}
+struct pthread_thread_init {
+ void* (*start_routine)(void*);
+ void* arg;
+};
+
+static DWORD CALLBACK pthread_thread_start(LPVOID data)
+{
+ struct pthread_thread_init init = *(struct pthread_thread_init*)data;
+ HeapFree(GetProcessHeap(),0,data);
+ return (DWORD)init.start_routine(init.arg);
+}
+
+int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void*
+ (*start_routine)(void *), void* arg)
+{
+ HANDLE hThread;
+ struct pthread_thread_init* idata = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(struct pthread_thread_init));
+
+ idata->start_routine = start_routine;
+ idata->arg = arg;
+ hThread = CreateThread(NULL, 0, pthread_thread_start, idata, 0, thread);
+
+ if(hThread)
+ CloseHandle(hThread);
+ else
+ {
+ HeapFree(GetProcessHeap(),0,idata); /* free idata struct on failure */
+ 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_detach\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;
diff --git a/scheduler/thread.c b/scheduler/thread.c
index aabee10..3df0807 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -382,6 +382,25 @@
}
}
+/***********************************************************************
+ * 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 = (void *)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.
diff --git a/server/protocol.def b/server/protocol.def
index 0cc3f26..a13fcc7 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -462,6 +462,16 @@
@END
+/* Open a handle to a thread */
+@REQ(open_thread)
+ void* tid; /* thread id to open */
+ unsigned int access; /* wanted access rights */
+ int inherit; /* inherit flag */
+@REPLY
+ handle_t handle; /* handle to the thread */
+@END
+
+
/* Wait for handles */
@REQ(select)
int flags; /* wait flags (see below) */
diff --git a/server/request.h b/server/request.h
index 7e3b507..99bba36 100644
--- a/server/request.h
+++ b/server/request.h
@@ -125,6 +125,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);
@@ -284,6 +285,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,
diff --git a/server/thread.c b/server/thread.c
index eba63e1..cf5dcf8 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -854,6 +854,19 @@
}
}
+/* 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 );
+ }
+}
+
/* fetch information about a thread */
DECL_HANDLER(get_thread_info)
{
diff --git a/server/trace.c b/server/trace.c
index a8844f1..cb2f19f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -638,6 +638,18 @@
fprintf( stderr, " handle=%d", req->handle );
}
+static void dump_open_thread_request( const struct open_thread_request *req )
+{
+ fprintf( stderr, " tid=%p,", req->tid );
+ fprintf( stderr, " access=%08x,", req->access );
+ fprintf( stderr, " inherit=%d", req->inherit );
+}
+
+static void dump_open_thread_reply( const struct open_thread_reply *req )
+{
+ fprintf( stderr, " handle=%d", req->handle );
+}
+
static void dump_select_request( const struct select_request *req )
{
fprintf( stderr, " flags=%d,", req->flags );
@@ -2177,6 +2189,7 @@
(dump_func)dump_set_handle_info_request,
(dump_func)dump_dup_handle_request,
(dump_func)dump_open_process_request,
+ (dump_func)dump_open_thread_request,
(dump_func)dump_select_request,
(dump_func)dump_create_event_request,
(dump_func)dump_event_op_request,
@@ -2333,6 +2346,7 @@
(dump_func)dump_set_handle_info_reply,
(dump_func)dump_dup_handle_reply,
(dump_func)dump_open_process_reply,
+ (dump_func)dump_open_thread_reply,
(dump_func)0,
(dump_func)dump_create_event_reply,
(dump_func)0,
@@ -2489,6 +2503,7 @@
"set_handle_info",
"dup_handle",
"open_process",
+ "open_thread",
"select",
"create_event",
"event_op",