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
4fac95df
Commit
4fac95df
authored
Feb 05, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed a couple of race conditions in the wine_pthread routines at
thread startup and exit.
parent
a5f816c6
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
96 additions
and
52 deletions
+96
-52
thread.c
dlls/kernel/thread.c
+17
-5
thread.c
dlls/ntdll/thread.c
+3
-1
pthread.h
include/wine/pthread.h
+2
-0
port.c
libs/wine/port.c
+7
-0
wine.def
libs/wine/wine.def
+1
-0
kthread.c
loader/kthread.c
+38
-28
pthread.c
loader/pthread.c
+28
-18
No files found.
dlls/kernel/thread.c
View file @
4fac95df
...
@@ -115,6 +115,22 @@ static void CALLBACK THREAD_Start( void *ptr )
...
@@ -115,6 +115,22 @@ static void CALLBACK THREAD_Start( void *ptr )
/***********************************************************************
/***********************************************************************
* cleanup_teb
*
* Cleanup the TEB structure; might be called from a different thread.
*/
static
void
cleanup_teb
(
struct
wine_pthread_thread_info
*
info
)
{
TEB
*
teb
=
(
TEB
*
)
info
->
teb_base
;
close
(
teb
->
wait_fd
[
0
]
);
close
(
teb
->
wait_fd
[
1
]
);
close
(
teb
->
reply_fd
);
close
(
teb
->
request_fd
);
}
/***********************************************************************
* CreateThread (KERNEL32.@)
* CreateThread (KERNEL32.@)
*/
*/
HANDLE
WINAPI
CreateThread
(
SECURITY_ATTRIBUTES
*
sa
,
SIZE_T
stack
,
HANDLE
WINAPI
CreateThread
(
SECURITY_ATTRIBUTES
*
sa
,
SIZE_T
stack
,
...
@@ -213,6 +229,7 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
...
@@ -213,6 +229,7 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
info
.
stack_base
=
NtCurrentTeb
()
->
DeallocationStack
;
info
.
stack_base
=
NtCurrentTeb
()
->
DeallocationStack
;
info
.
teb_base
=
NtCurrentTeb
();
info
.
teb_base
=
NtCurrentTeb
();
info
.
teb_sel
=
wine_get_fs
();
info
.
teb_sel
=
wine_get_fs
();
info
.
cleanup
=
cleanup_teb
;
info
.
exit_status
=
code
;
info
.
exit_status
=
code
;
size
=
0
;
size
=
0
;
...
@@ -234,11 +251,6 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
...
@@ -234,11 +251,6 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
sigaddset
(
&
block_set
,
SIGTERM
);
sigaddset
(
&
block_set
,
SIGTERM
);
sigprocmask
(
SIG_BLOCK
,
&
block_set
,
NULL
);
sigprocmask
(
SIG_BLOCK
,
&
block_set
,
NULL
);
close
(
NtCurrentTeb
()
->
wait_fd
[
0
]
);
close
(
NtCurrentTeb
()
->
wait_fd
[
1
]
);
close
(
NtCurrentTeb
()
->
reply_fd
);
close
(
NtCurrentTeb
()
->
request_fd
);
wine_pthread_exit_thread
(
&
info
);
wine_pthread_exit_thread
(
&
info
);
}
}
}
}
...
...
dlls/ntdll/thread.c
View file @
4fac95df
...
@@ -129,6 +129,7 @@ void thread_init(void)
...
@@ -129,6 +129,7 @@ void thread_init(void)
thread_info
.
teb_base
=
teb
;
thread_info
.
teb_base
=
teb
;
thread_info
.
teb_size
=
size
;
thread_info
.
teb_size
=
size
;
thread_info
.
teb_sel
=
teb
->
teb_sel
;
thread_info
.
teb_sel
=
teb
->
teb_sel
;
wine_pthread_init_current_teb
(
&
thread_info
);
wine_pthread_init_thread
(
&
thread_info
);
wine_pthread_init_thread
(
&
thread_info
);
debug_info
.
str_pos
=
debug_info
.
strings
;
debug_info
.
str_pos
=
debug_info
.
strings
;
...
@@ -171,9 +172,10 @@ static void start_thread( struct wine_pthread_thread_info *info )
...
@@ -171,9 +172,10 @@ static void start_thread( struct wine_pthread_thread_info *info )
debug_info
.
out_pos
=
debug_info
.
output
;
debug_info
.
out_pos
=
debug_info
.
output
;
teb
->
debug_info
=
&
debug_info
;
teb
->
debug_info
=
&
debug_info
;
wine_pthread_init_
thread
(
info
);
wine_pthread_init_
current_teb
(
info
);
SIGNAL_Init
();
SIGNAL_Init
();
server_init_thread
(
info
->
pid
,
info
->
tid
,
func
);
server_init_thread
(
info
->
pid
,
info
->
tid
,
func
);
wine_pthread_init_thread
(
info
);
/* allocate a memory view for the stack */
/* allocate a memory view for the stack */
size
=
info
->
stack_size
;
size
=
info
->
stack_size
;
...
...
include/wine/pthread.h
View file @
4fac95df
...
@@ -94,12 +94,14 @@ struct wine_pthread_thread_info
...
@@ -94,12 +94,14 @@ struct wine_pthread_thread_info
int
pid
;
/* Unix process id */
int
pid
;
/* Unix process id */
int
tid
;
/* Unix thread id */
int
tid
;
/* Unix thread id */
void
(
*
entry
)(
struct
wine_pthread_thread_info
*
info
);
/* thread entry point */
void
(
*
entry
)(
struct
wine_pthread_thread_info
*
info
);
/* thread entry point */
void
(
*
cleanup
)(
struct
wine_pthread_thread_info
*
info
);
/* thread cleanup function */
int
exit_status
;
/* thread exit status when calling wine_pthread_exit_thread */
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_process
(
const
struct
wine_pthread_functions
*
functions
);
extern
void
wine_pthread_init_thread
(
struct
wine_pthread_thread_info
*
info
);
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
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
*
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_exit_thread
(
struct
wine_pthread_thread_info
*
info
);
extern
void
DECLSPEC_NORETURN
wine_pthread_abort_thread
(
int
status
);
extern
void
DECLSPEC_NORETURN
wine_pthread_abort_thread
(
int
status
);
...
...
libs/wine/port.c
View file @
4fac95df
...
@@ -67,6 +67,13 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
...
@@ -67,6 +67,13 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
}
}
/***********************************************************************
/***********************************************************************
* wine_pthread_init_current_teb
*/
void
wine_pthread_init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
}
/***********************************************************************
* wine_pthread_get_current_teb
* wine_pthread_get_current_teb
*/
*/
void
*
wine_pthread_get_current_teb
(
void
)
void
*
wine_pthread_get_current_teb
(
void
)
...
...
libs/wine/wine.def
View file @
4fac95df
...
@@ -59,6 +59,7 @@ EXPORTS
...
@@ -59,6 +59,7 @@ EXPORTS
wine_pthread_abort_thread
wine_pthread_abort_thread
wine_pthread_create_thread
wine_pthread_create_thread
wine_pthread_exit_thread
wine_pthread_exit_thread
wine_pthread_init_current_teb
wine_pthread_init_process
wine_pthread_init_process
wine_pthread_init_thread
wine_pthread_init_thread
wine_set_fs
wine_set_fs
...
...
loader/kthread.c
View file @
4fac95df
...
@@ -189,6 +189,7 @@ static void cleanup_thread( void *ptr )
...
@@ -189,6 +189,7 @@ static void cleanup_thread( void *ptr )
{
{
/* copy the info structure since it is on the stack we will free */
/* copy the info structure since it is on the stack we will free */
struct
wine_pthread_thread_info
info
=
*
(
struct
wine_pthread_thread_info
*
)
ptr
;
struct
wine_pthread_thread_info
info
=
*
(
struct
wine_pthread_thread_info
*
)
ptr
;
if
(
info
.
cleanup
)
info
.
cleanup
(
&
info
);
wine_ldt_free_fs
(
info
.
teb_sel
);
wine_ldt_free_fs
(
info
.
teb_sel
);
munmap
(
info
.
stack_base
,
info
.
stack_size
);
munmap
(
info
.
stack_base
,
info
.
stack_size
);
munmap
(
info
.
teb_base
,
info
.
teb_size
);
munmap
(
info
.
teb_base
,
info
.
teb_size
);
...
@@ -220,34 +221,6 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
...
@@ -220,34 +221,6 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
{
{
struct
pthread_descr_struct
*
descr
;
struct
pthread_descr_struct
*
descr
;
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
LDT_ENTRY
fs_entry
;
wine_ldt_set_base
(
&
fs_entry
,
info
->
teb_base
);
wine_ldt_set_limit
(
&
fs_entry
,
info
->
teb_size
-
1
);
wine_ldt_set_flags
(
&
fs_entry
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
wine_ldt_init_fs
(
info
->
teb_sel
,
&
fs_entry
);
#elif defined(__powerpc__)
/* On PowerPC, the current TEB is in the gpr13 register */
# ifdef __APPLE__
__asm__
__volatile__
(
"mr r13, %0"
:
:
"r"
(
info
->
teb_base
));
# else
__asm__
__volatile__
(
"mr 2, %0"
:
:
"r"
(
info
->
teb_base
));
# endif
#elif defined(HAVE__LWP_CREATE)
/* On non-i386 Solaris, we use the LWP private pointer */
_lwp_setprivate
(
info
->
teb_base
);
#endif
/* set pid and tid */
info
->
pid
=
getpid
();
#ifdef HAVE__LWP_SELF
info
->
tid
=
_lwp_self
();
#else
info
->
tid
=
-
1
;
#endif
if
(
funcs
.
ptr_set_thread_data
)
if
(
funcs
.
ptr_set_thread_data
)
{
{
descr
=
calloc
(
1
,
sizeof
(
*
descr
)
);
descr
=
calloc
(
1
,
sizeof
(
*
descr
)
);
...
@@ -319,6 +292,43 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
...
@@ -319,6 +292,43 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
/***********************************************************************
* wine_pthread_init_current_teb
*
* Set the current TEB for a new thread.
*/
void
wine_pthread_init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
LDT_ENTRY
fs_entry
;
wine_ldt_set_base
(
&
fs_entry
,
info
->
teb_base
);
wine_ldt_set_limit
(
&
fs_entry
,
info
->
teb_size
-
1
);
wine_ldt_set_flags
(
&
fs_entry
,
WINE_LDT_FLAGS_DATA
|
WINE_LDT_FLAGS_32BIT
);
wine_ldt_init_fs
(
info
->
teb_sel
,
&
fs_entry
);
#elif defined(__powerpc__)
/* On PowerPC, the current TEB is in the gpr13 register */
# ifdef __APPLE__
__asm__
__volatile__
(
"mr r13, %0"
:
:
"r"
(
info
->
teb_base
));
# else
__asm__
__volatile__
(
"mr 2, %0"
:
:
"r"
(
info
->
teb_base
));
# endif
#elif defined(HAVE__LWP_CREATE)
/* On non-i386 Solaris, we use the LWP private pointer */
_lwp_setprivate
(
info
->
teb_base
);
#endif
/* set pid and tid */
info
->
pid
=
getpid
();
#ifdef HAVE__LWP_SELF
info
->
tid
=
_lwp_self
();
#else
info
->
tid
=
-
1
;
#endif
}
/***********************************************************************
* wine_pthread_get_current_teb
* wine_pthread_get_current_teb
*/
*/
void
*
wine_pthread_get_current_teb
(
void
)
void
*
wine_pthread_get_current_teb
(
void
)
...
...
loader/pthread.c
View file @
4fac95df
...
@@ -62,20 +62,6 @@ void wine_pthread_init_process( const struct wine_pthread_functions *functions )
...
@@ -62,20 +62,6 @@ void wine_pthread_init_process( const struct wine_pthread_functions *functions )
*/
*/
void
wine_pthread_init_thread
(
struct
wine_pthread_thread_info
*
info
)
void
wine_pthread_init_thread
(
struct
wine_pthread_thread_info
*
info
)
{
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
LDT_ENTRY
fs_entry
;
wine_ldt_set_base
(
&
fs_entry
,
info
->
teb_base
);
wine_ldt_set_limit
(
&
fs_entry
,
info
->
teb_size
-
1
);
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 */
pthread_key_create
(
&
teb_key
,
NULL
);
pthread_setspecific
(
teb_key
,
info
->
teb_base
);
#endif
/* retrieve the stack info (except for main thread) */
/* retrieve the stack info (except for main thread) */
if
(
funcs
.
ptr_set_thread_data
)
if
(
funcs
.
ptr_set_thread_data
)
{
{
...
@@ -91,10 +77,6 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
...
@@ -91,10 +77,6 @@ void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
info
->
stack_base
=
stack_top
-
info
->
stack_size
;
info
->
stack_base
=
stack_top
-
info
->
stack_size
;
#endif
#endif
}
}
/* set pid and tid */
info
->
pid
=
getpid
();
info
->
tid
=
gettid
();
}
}
...
@@ -116,6 +98,33 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
...
@@ -116,6 +98,33 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
/***********************************************************************
* wine_pthread_init_current_teb
*
* Set the current TEB for a new thread.
*/
void
wine_pthread_init_current_teb
(
struct
wine_pthread_thread_info
*
info
)
{
#ifdef __i386__
/* On the i386, the current thread is in the %fs register */
LDT_ENTRY
fs_entry
;
wine_ldt_set_base
(
&
fs_entry
,
info
->
teb_base
);
wine_ldt_set_limit
(
&
fs_entry
,
info
->
teb_size
-
1
);
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 */
pthread_key_create
(
&
teb_key
,
NULL
);
pthread_setspecific
(
teb_key
,
info
->
teb_base
);
#endif
/* set pid and tid */
info
->
pid
=
getpid
();
info
->
tid
=
gettid
();
}
/***********************************************************************
* wine_pthread_get_current_teb
* wine_pthread_get_current_teb
*/
*/
void
*
wine_pthread_get_current_teb
(
void
)
void
*
wine_pthread_get_current_teb
(
void
)
...
@@ -153,6 +162,7 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
...
@@ -153,6 +162,7 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
if
((
free_info
=
interlocked_xchg_ptr
(
(
void
**
)
&
previous_info
,
cleanup_info
))
!=
NULL
)
if
((
free_info
=
interlocked_xchg_ptr
(
(
void
**
)
&
previous_info
,
cleanup_info
))
!=
NULL
)
{
{
pthread_join
(
free_info
->
self
,
&
ptr
);
pthread_join
(
free_info
->
self
,
&
ptr
);
if
(
free_info
->
thread_info
.
cleanup
)
free_info
->
thread_info
.
cleanup
(
&
free_info
->
thread_info
);
wine_ldt_free_fs
(
free_info
->
thread_info
.
teb_sel
);
wine_ldt_free_fs
(
free_info
->
thread_info
.
teb_sel
);
munmap
(
free_info
->
thread_info
.
teb_base
,
free_info
->
thread_info
.
teb_size
);
munmap
(
free_info
->
thread_info
.
teb_base
,
free_info
->
thread_info
.
teb_size
);
}
}
...
...
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