Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
883d3c52
Commit
883d3c52
authored
Sep 03, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use explicit function pointers for pthread support instead of relying
on ELF symbol overriding.
parent
8a5f8937
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
121 additions
and
124 deletions
+121
-124
pthread.c
dlls/kernel/pthread.c
+12
-10
thread.c
dlls/kernel/thread.c
+0
-1
server.c
dlls/ntdll/server.c
+4
-2
thread.c
dlls/ntdll/thread.c
+8
-6
pthread.h
include/wine/pthread.h
+15
-10
port.c
libs/wine/port.c
+7
-45
wine.def
libs/wine/wine.def
+2
-7
wine.map
libs/wine/wine.map
+2
-7
kthread.c
loader/kthread.c
+33
-18
main.c
loader/main.c
+1
-0
main.h
loader/main.h
+4
-0
pthread.c
loader/pthread.c
+33
-18
No files found.
dlls/kernel/pthread.c
View file @
883d3c52
...
...
@@ -354,7 +354,7 @@ static void wine_cond_real_init(pthread_cond_t *cond)
}
}
int
wine_pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
cond_attr
)
static
int
wine_pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
cond_attr
)
{
/* The same as for wine_pthread_mutex_init, we postpone initialization
until condition is really used.*/
...
...
@@ -362,7 +362,7 @@ int wine_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_
return
0
;
}
int
wine_pthread_cond_destroy
(
pthread_cond_t
*
cond
)
static
int
wine_pthread_cond_destroy
(
pthread_cond_t
*
cond
)
{
wine_cond_detail
*
detail
=
((
wine_cond
)
cond
)
->
cond
;
...
...
@@ -375,7 +375,7 @@ int wine_pthread_cond_destroy(pthread_cond_t *cond)
return
0
;
}
int
wine_pthread_cond_signal
(
pthread_cond_t
*
cond
)
static
int
wine_pthread_cond_signal
(
pthread_cond_t
*
cond
)
{
int
have_waiters
;
wine_cond_detail
*
detail
;
...
...
@@ -394,7 +394,7 @@ int wine_pthread_cond_signal(pthread_cond_t *cond)
return
0
;
}
int
wine_pthread_cond_broadcast
(
pthread_cond_t
*
cond
)
static
int
wine_pthread_cond_broadcast
(
pthread_cond_t
*
cond
)
{
int
have_waiters
=
0
;
wine_cond_detail
*
detail
;
...
...
@@ -438,7 +438,7 @@ int wine_pthread_cond_broadcast(pthread_cond_t *cond)
return
0
;
}
int
wine_pthread_cond_wait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
)
static
int
wine_pthread_cond_wait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
)
{
wine_cond_detail
*
detail
;
int
last_waiter
;
...
...
@@ -474,8 +474,8 @@ int wine_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
return
0
;
}
int
wine_pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
)
static
int
wine_pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
struct
timespec
*
abstime
)
{
DWORD
ms
=
abstime
->
tv_sec
*
1000
+
abstime
->
tv_nsec
/
1000000
;
int
last_waiter
;
...
...
@@ -539,9 +539,8 @@ static void wine_set_thread_data( void *data )
kernel_get_thread_data
()
->
pthread_data
=
data
;
}
static
const
struct
wine_pthread_
functions
function
s
=
static
const
struct
wine_pthread_
callbacks
callback
s
=
{
sizeof
(
functions
),
/* size */
wine_get_thread_data
,
/* ptr_get_thread_data */
wine_set_thread_data
,
/* ptr_set_thread_data */
wine_pthread_self
,
/* ptr_pthread_self */
...
...
@@ -571,9 +570,12 @@ static const struct wine_pthread_functions functions =
wine_pthread_cond_timedwait
/* ptr_pthread_cond_timedwait */
};
static
struct
wine_pthread_functions
pthread_functions
;
void
PTHREAD_Init
(
void
)
{
wine_pthread_init_process
(
&
functions
);
wine_pthread_get_functions
(
&
pthread_functions
,
sizeof
(
pthread_functions
)
);
pthread_functions
.
init_process
(
&
callbacks
,
sizeof
(
callbacks
)
);
}
#endif
/* HAVE_PTHREAD_H */
dlls/kernel/thread.c
View file @
883d3c52
...
...
@@ -42,7 +42,6 @@
#include "wine/winbase16.h"
#include "wine/exception.h"
#include "wine/library.h"
#include "wine/pthread.h"
#include "wine/server.h"
#include "wine/debug.h"
...
...
dlls/ntdll/server.c
View file @
883d3c52
...
...
@@ -83,6 +83,8 @@ struct cmsg_fd
time_t
server_start_time
=
0
;
/* time of server startup */
extern
struct
wine_pthread_functions
pthread_functions
;
static
sigset_t
block_set
;
/* signals to block during server calls */
static
int
fd_socket
=
-
1
;
/* socket to exchange file descriptors with the server */
...
...
@@ -148,7 +150,7 @@ void server_exit_thread( int status )
close
(
ntdll_get_thread_data
()
->
wait_fd
[
1
]
);
close
(
ntdll_get_thread_data
()
->
reply_fd
);
close
(
ntdll_get_thread_data
()
->
request_fd
);
wine_pthread_
exit_thread
(
&
info
);
pthread_functions
.
exit_thread
(
&
info
);
}
...
...
@@ -162,7 +164,7 @@ void server_abort_thread( int status )
close
(
ntdll_get_thread_data
()
->
wait_fd
[
1
]
);
close
(
ntdll_get_thread_data
()
->
reply_fd
);
close
(
ntdll_get_thread_data
()
->
request_fd
);
wine_pthread_
abort_thread
(
status
);
pthread_functions
.
abort_thread
(
status
);
}
...
...
dlls/ntdll/thread.c
View file @
883d3c52
...
...
@@ -53,6 +53,7 @@ static RTL_BITMAP tls_bitmap;
static
RTL_BITMAP
tls_expansion_bitmap
;
static
LIST_ENTRY
tls_links
;
struct
wine_pthread_functions
pthread_functions
=
{
NULL
};
/***********************************************************************
* init_teb
...
...
@@ -136,8 +137,9 @@ void thread_init(void)
thread_info
.
stack_size
=
0
;
thread_info
.
teb_base
=
teb
;
thread_info
.
teb_sel
=
thread_data
->
teb_sel
;
wine_pthread_init_current_teb
(
&
thread_info
);
wine_pthread_init_thread
(
&
thread_info
);
wine_pthread_get_functions
(
&
pthread_functions
,
sizeof
(
pthread_functions
)
);
pthread_functions
.
init_current_teb
(
&
thread_info
);
pthread_functions
.
init_thread
(
&
thread_info
);
debug_info
.
str_pos
=
debug_info
.
strings
;
debug_info
.
out_pos
=
debug_info
.
output
;
...
...
@@ -197,10 +199,10 @@ static void start_thread( struct wine_pthread_thread_info *info )
debug_info
.
out_pos
=
debug_info
.
output
;
thread_data
->
debug_info
=
&
debug_info
;
wine_pthread_
init_current_teb
(
info
);
pthread_functions
.
init_current_teb
(
info
);
SIGNAL_Init
();
server_init_thread
(
info
->
pid
,
info
->
tid
,
func
);
wine_pthread_
init_thread
(
info
);
pthread_functions
.
init_thread
(
info
);
/* allocate a memory view for the stack */
size
=
info
->
stack_size
;
...
...
@@ -305,7 +307,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
info
->
entry_point
=
start
;
info
->
entry_arg
=
param
;
if
(
wine_pthread_
create_thread
(
&
info
->
pthread_info
)
==
-
1
)
if
(
pthread_functions
.
create_thread
(
&
info
->
pthread_info
)
==
-
1
)
{
status
=
STATUS_NO_MEMORY
;
goto
error
;
...
...
@@ -673,7 +675,7 @@ __ASM_GLOBAL_FUNC( NtCurrentTeb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
TEB
*
WINAPI
NtCurrentTeb
(
void
)
{
return
wine_pthread_
get_current_teb
();
return
pthread_functions
.
get_current_teb
();
}
#endif
/* __i386__ */
include/wine/pthread.h
View file @
883d3c52
...
...
@@ -21,7 +21,7 @@
#ifndef __WINE_WINE_PTHREAD_H
#define __WINE_WINE_PTHREAD_H
struct
wine_pthread_
function
s
;
struct
wine_pthread_
callback
s
;
#ifdef HAVE_PTHREAD_H
...
...
@@ -35,9 +35,8 @@ typedef void *pthread_rwlock_t;
typedef
void
*
pthread_rwlockattr_t
;
#endif
struct
wine_pthread_
function
s
struct
wine_pthread_
callback
s
{
size_t
size
;
void
*
(
*
ptr_get_thread_data
)(
void
);
void
(
*
ptr_set_thread_data
)(
void
*
data
);
pthread_t
(
*
ptr_pthread_self
)(
void
);
...
...
@@ -97,12 +96,18 @@ struct wine_pthread_thread_info
int
exit_status
;
/* thread exit status when calling wine_pthread_exit_thread */
};
extern
void
wine_pthread_init_process
(
const
struct
wine_pthread_functions
*
functions
);
extern
void
wine_pthread_init_thread
(
struct
wine_pthread_thread_info
*
info
);
extern
int
wine_pthread_create_thread
(
struct
wine_pthread_thread_info
*
info
);
extern
void
wine_pthread_init_current_teb
(
struct
wine_pthread_thread_info
*
info
);
extern
void
*
wine_pthread_get_current_teb
(
void
);
extern
void
DECLSPEC_NORETURN
wine_pthread_exit_thread
(
struct
wine_pthread_thread_info
*
info
);
extern
void
DECLSPEC_NORETURN
wine_pthread_abort_thread
(
int
status
);
struct
wine_pthread_functions
{
void
(
*
init_process
)(
const
struct
wine_pthread_callbacks
*
callbacks
,
size_t
size
);
void
(
*
init_thread
)(
struct
wine_pthread_thread_info
*
info
);
int
(
*
create_thread
)(
struct
wine_pthread_thread_info
*
info
);
void
(
*
init_current_teb
)(
struct
wine_pthread_thread_info
*
info
);
void
*
(
*
get_current_teb
)(
void
);
void
(
*
DECLSPEC_NORETURN
exit_thread
)(
struct
wine_pthread_thread_info
*
info
);
void
(
*
DECLSPEC_NORETURN
abort_thread
)(
int
status
);
};
extern
void
wine_pthread_get_functions
(
struct
wine_pthread_functions
*
functions
,
size_t
size
);
extern
void
wine_pthread_set_functions
(
const
struct
wine_pthread_functions
*
functions
,
size_t
size
);
#endif
/* __WINE_WINE_PTHREAD_H */
libs/wine/port.c
View file @
883d3c52
...
...
@@ -28,61 +28,23 @@
#include "wine/library.h"
#include "wine/pthread.h"
/* Note: the wine_pthread functions are just placeholders,
* they will be overridden by the pthread support code.
*/
static
struct
wine_pthread_functions
pthread_functions
;
/***********************************************************************
* wine_pthread_
init_proces
s
* wine_pthread_
get_function
s
*/
void
wine_pthread_
init_process
(
const
struct
wine_pthread_functions
*
functions
)
void
wine_pthread_
get_functions
(
struct
wine_pthread_functions
*
functions
,
size_t
size
)
{
memcpy
(
functions
,
&
pthread_functions
,
min
(
size
,
sizeof
(
pthread_functions
)
));
}
/***********************************************************************
* wine_pthread_init_thread
*/
void
wine_pthread_init_thread
(
struct
wine_pthread_thread_info
*
info
)
{
}
/***********************************************************************
* wine_pthread_create_thread
*/
int
wine_pthread_create_thread
(
struct
wine_pthread_thread_info
*
info
)
{
return
-
1
;
}
/***********************************************************************
* wine_pthread_init_current_teb
*/
void
wine_pthread_init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
}
/***********************************************************************
* wine_pthread_get_current_teb
*/
void
*
wine_pthread_get_current_teb
(
void
)
{
return
NULL
;
}
/***********************************************************************
* wine_pthread_exit_thread
*/
void
wine_pthread_exit_thread
(
struct
wine_pthread_thread_info
*
info
)
{
exit
(
info
->
exit_status
);
}
/***********************************************************************
* wine_pthread_
abort_thread
* wine_pthread_
set_functions
*/
void
wine_pthread_
abort_thread
(
int
status
)
void
wine_pthread_
set_functions
(
const
struct
wine_pthread_functions
*
functions
,
size_t
size
)
{
exit
(
status
);
memcpy
(
&
pthread_functions
,
functions
,
min
(
size
,
sizeof
(
pthread_functions
)
)
);
}
...
...
libs/wine/wine.def
View file @
883d3c52
...
...
@@ -58,13 +58,8 @@ EXPORTS
wine_mmap_add_reserved_area
wine_mmap_is_in_reserved_area
wine_mmap_remove_reserved_area
wine_pthread_abort_thread
wine_pthread_create_thread
wine_pthread_exit_thread
wine_pthread_get_current_teb
wine_pthread_init_current_teb
wine_pthread_init_process
wine_pthread_init_thread
wine_pthread_get_functions
wine_pthread_set_functions
wine_set_fs
wine_set_gs
wine_switch_to_stack
libs/wine/wine.map
View file @
883d3c52
...
...
@@ -58,13 +58,8 @@ WINE_1.0
wine_mmap_add_reserved_area;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
wine_pthread_abort_thread;
wine_pthread_create_thread;
wine_pthread_exit_thread;
wine_pthread_get_current_teb;
wine_pthread_init_current_teb;
wine_pthread_init_process;
wine_pthread_init_thread;
wine_pthread_get_functions;
wine_pthread_set_functions;
wine_set_fs;
wine_set_gs;
wine_switch_to_stack;
...
...
loader/kthread.c
View file @
883d3c52
...
...
@@ -75,7 +75,7 @@ struct _pthread_cleanup_buffer;
#define PSTR(str) __ASM_NAME(#str)
static
struct
wine_pthread_
function
s
funcs
;
static
struct
wine_pthread_
callback
s
funcs
;
/* thread descriptor */
...
...
@@ -200,23 +200,23 @@ static void cleanup_thread( void *ptr )
/***********************************************************************
*
wine_pthread_
init_process
* init_process
*
* Initialization for a newly created process.
*/
void
wine_pthread_init_process
(
const
struct
wine_pthread_functions
*
functions
)
static
void
init_process
(
const
struct
wine_pthread_callbacks
*
callbacks
,
size_t
size
)
{
memcpy
(
&
funcs
,
functions
,
min
(
functions
->
size
,
sizeof
(
funcs
))
);
memcpy
(
&
funcs
,
callbacks
,
min
(
size
,
sizeof
(
funcs
)
)
);
funcs
.
ptr_set_thread_data
(
&
initial_descr
);
}
/***********************************************************************
*
wine_pthread_
init_thread
* init_thread
*
* Initialization for a newly created thread.
*/
void
wine_pthread_
init_thread
(
struct
wine_pthread_thread_info
*
info
)
static
void
init_thread
(
struct
wine_pthread_thread_info
*
info
)
{
struct
pthread_descr_struct
*
descr
;
...
...
@@ -240,9 +240,9 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
create_thread
* create_thread
*/
int
wine_pthread_
create_thread
(
struct
wine_pthread_thread_info
*
info
)
static
int
create_thread
(
struct
wine_pthread_thread_info
*
info
)
{
if
(
!
info
->
stack_base
)
{
...
...
@@ -291,11 +291,11 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
init_current_teb
* init_current_teb
*
* Set the current TEB for a new thread.
*/
void
wine_pthread_
init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
static
void
init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
...
...
@@ -319,7 +319,7 @@ void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
/* FIXME: On Alpha, the current TEB is not accessible to user-space */
/* __asm__ __volatile__();*/
#else
# error You must implement
wine_pthread_
init_current_teb for your platform
# error You must implement init_current_teb for your platform
#endif
/* set pid and tid */
...
...
@@ -333,9 +333,9 @@ void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
get_current_teb
* get_current_teb
*/
void
*
wine_pthread_
get_current_teb
(
void
)
static
void
*
get_current_teb
(
void
)
{
void
*
ret
;
...
...
@@ -358,7 +358,7 @@ void *wine_pthread_get_current_teb(void)
"ldq $0,0($30)
\n\t
"
"lda $30,-8($30)"
:
"=r"
(
ret
)
);
#else
# error
wine_pthread_
get_current_teb not defined for this architecture
# error get_current_teb not defined for this architecture
#endif
/* __i386__ */
return
ret
;
...
...
@@ -366,18 +366,18 @@ void *wine_pthread_get_current_teb(void)
/***********************************************************************
*
wine_pthread_
exit_thread
* exit_thread
*/
void
wine_pthread_
exit_thread
(
struct
wine_pthread_thread_info
*
info
)
static
void
DECLSPEC_NORETURN
exit_thread
(
struct
wine_pthread_thread_info
*
info
)
{
wine_switch_to_stack
(
cleanup_thread
,
info
,
get_temp_stack
()
);
}
/***********************************************************************
*
wine_pthread_
abort_thread
* abort_thread
*/
void
wine_pthread_
abort_thread
(
int
status
)
static
void
DECLSPEC_NORETURN
abort_thread
(
int
status
)
{
#ifdef HAVE__LWP_CREATE
_lwp_exit
();
...
...
@@ -386,6 +386,21 @@ void wine_pthread_abort_thread( int status )
}
/***********************************************************************
* pthread_functions
*/
const
struct
wine_pthread_functions
pthread_functions
=
{
init_process
,
init_thread
,
create_thread
,
init_current_teb
,
get_current_teb
,
exit_thread
,
abort_thread
};
/* Currently this probably works only for glibc2,
* which checks for the presence of double-underscore-prepended
* pthread primitives, and use them if available.
...
...
loader/main.c
View file @
883d3c52
...
...
@@ -41,6 +41,7 @@ int main( int argc, char *argv[] )
wine_main_preload_info
[
i
].
size
);
}
wine_pthread_set_functions
(
&
pthread_functions
,
sizeof
(
pthread_functions
)
);
wine_init
(
argc
,
argv
,
error
,
sizeof
(
error
)
);
fprintf
(
stderr
,
"wine: failed to initialize: %s
\n
"
,
error
);
exit
(
1
);
...
...
loader/main.h
View file @
883d3c52
...
...
@@ -22,10 +22,14 @@
#ifndef __WINE_LOADER_MAIN_H
#define __WINE_LOADER_MAIN_H
#include "wine/pthread.h"
struct
wine_preload_info
{
void
*
addr
;
size_t
size
;
};
extern
const
struct
wine_pthread_functions
pthread_functions
;
#endif
/* __WINE_LOADER_MAIN_H */
loader/pthread.c
View file @
883d3c52
...
...
@@ -38,32 +38,32 @@
#include "wine/library.h"
#include "wine/pthread.h"
static
struct
wine_pthread_functions
funcs
;
static
int
init_done
;
#ifndef __i386__
static
pthread_key_t
teb_key
;
#endif
/***********************************************************************
*
wine_pthread_
init_process
* init_process
*
* Initialization for a newly created process.
*/
void
wine_pthread_init_process
(
const
struct
wine_pthread_functions
*
functions
)
static
void
init_process
(
const
struct
wine_pthread_callbacks
*
callbacks
,
size_t
size
)
{
memcpy
(
&
funcs
,
functions
,
min
(
functions
->
size
,
sizeof
(
funcs
))
)
;
init_done
=
1
;
}
/***********************************************************************
*
wine_pthread_
init_thread
* init_thread
*
* Initialization for a newly created thread.
*/
void
wine_pthread_
init_thread
(
struct
wine_pthread_thread_info
*
info
)
static
void
init_thread
(
struct
wine_pthread_thread_info
*
info
)
{
/* retrieve the stack info (except for main thread) */
if
(
funcs
.
ptr_set_thread_data
)
if
(
init_done
)
{
#ifdef HAVE_PTHREAD_GETATTR_NP
pthread_attr_t
attr
;
...
...
@@ -84,9 +84,9 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
create_thread
* create_thread
*/
int
wine_pthread_
create_thread
(
struct
wine_pthread_thread_info
*
info
)
static
int
create_thread
(
struct
wine_pthread_thread_info
*
info
)
{
pthread_t
id
;
pthread_attr_t
attr
;
...
...
@@ -102,11 +102,11 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
init_current_teb
* init_current_teb
*
* Set the current TEB for a new thread.
*/
void
wine_pthread_
init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
static
void
init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
...
...
@@ -117,7 +117,7 @@ void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
wine_ldt_set_flags
(
&
fs_entry
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
wine_ldt_init_fs
(
info
->
teb_sel
,
&
fs_entry
);
#else
if
(
!
funcs
.
ptr_set_thread_data
)
/* first thread */
if
(
!
init_done
)
/* first thread */
pthread_key_create
(
&
teb_key
,
NULL
);
pthread_setspecific
(
teb_key
,
info
->
teb_base
);
#endif
...
...
@@ -129,9 +129,9 @@ void wine_pthread_init_current_teb( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
get_current_teb
* get_current_teb
*/
void
*
wine_pthread_
get_current_teb
(
void
)
static
void
*
get_current_teb
(
void
)
{
#ifdef __i386__
void
*
ret
;
...
...
@@ -144,9 +144,9 @@ void *wine_pthread_get_current_teb(void)
/***********************************************************************
*
wine_pthread_
exit_thread
* exit_thread
*/
void
wine_pthread_
exit_thread
(
struct
wine_pthread_thread_info
*
info
)
static
void
DECLSPEC_NORETURN
exit_thread
(
struct
wine_pthread_thread_info
*
info
)
{
wine_ldt_free_fs
(
info
->
teb_sel
);
munmap
(
info
->
teb_base
,
info
->
teb_size
);
...
...
@@ -155,11 +155,26 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
*
wine_pthread_
abort_thread
* abort_thread
*/
void
wine_pthread_
abort_thread
(
int
status
)
static
void
DECLSPEC_NORETURN
abort_thread
(
int
status
)
{
pthread_exit
(
(
void
*
)
status
);
}
/***********************************************************************
* pthread_functions
*/
const
struct
wine_pthread_functions
pthread_functions
=
{
init_process
,
init_thread
,
create_thread
,
init_current_teb
,
get_current_teb
,
exit_thread
,
abort_thread
};
#endif
/* HAVE_PTHREAD_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment