Implement OpenThread() winapi call.
Implement a few pthreads functions.
This commit is contained in:
parent
3320b43404
commit
417296c4af
|
@ -594,6 +594,7 @@ debug_channels (comm console debugstr dll int resource stress thunk toolhelp
|
|||
@ 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 @@ debug_channels (comm console debugstr dll int resource stress thunk toolhelp
|
|||
@ 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
|
||||
|
|
|
@ -1328,23 +1328,24 @@ BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE);
|
|||
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);
|
||||
|
|
|
@ -573,6 +573,21 @@ struct open_process_reply
|
|||
|
||||
|
||||
|
||||
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 @@ enum request
|
|||
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 @@ union generic_request
|
|||
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 @@ union generic_reply
|
|||
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 @@ union generic_reply
|
|||
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 */
|
||||
|
|
|
@ -124,6 +124,100 @@ void __pthread_initialize(void)
|
|||
{
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -382,6 +382,25 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
|
|||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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.
|
||||
|
|
|
@ -462,6 +462,16 @@ enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC };
|
|||
@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) */
|
||||
|
|
|
@ -125,6 +125,7 @@ DECL_HANDLER(close_handle);
|
|||
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 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(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,
|
||||
|
|
|
@ -854,6 +854,19 @@ DECL_HANDLER(terminate_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 );
|
||||
}
|
||||
}
|
||||
|
||||
/* fetch information about a thread */
|
||||
DECL_HANDLER(get_thread_info)
|
||||
{
|
||||
|
|
|
@ -638,6 +638,18 @@ static void dump_open_process_reply( const struct open_process_reply *req )
|
|||
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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(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 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"set_handle_info",
|
||||
"dup_handle",
|
||||
"open_process",
|
||||
"open_thread",
|
||||
"select",
|
||||
"create_event",
|
||||
"event_op",
|
||||
|
|
Loading…
Reference in New Issue