Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
9de03f4f
Commit
9de03f4f
authored
Jan 04, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made sleep_on usable from all requests.
parent
28237782
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
85 additions
and
91 deletions
+85
-91
request.c
server/request.c
+2
-12
request.h
server/request.h
+0
-2
thread.c
server/thread.c
+78
-67
thread.h
server/thread.h
+5
-5
trace.c
server/trace.c
+0
-5
No files found.
server/request.c
View file @
9de03f4f
...
...
@@ -76,23 +76,13 @@ static void call_req_handler( struct thread *thread, enum request req, int fd )
if
(
req
<
REQ_NB_REQUESTS
)
{
req_handlers
[
req
].
handler
(
current
->
buffer
,
fd
);
if
(
current
&&
current
->
state
!=
SLEEPING
)
send_reply
(
current
);
if
(
current
&&
!
current
->
wait
)
send_reply
(
current
);
current
=
NULL
;
return
;
}
fatal_protocol_error
(
current
,
"bad request %d
\n
"
,
req
);
}
/* handle a client timeout */
void
call_timeout_handler
(
void
*
thread
)
{
current
=
(
struct
thread
*
)
thread
;
if
(
debug_level
)
trace_timeout
();
clear_error
();
thread_timeout
();
current
=
NULL
;
}
/* set the fd to pass to the thread */
void
set_reply_fd
(
struct
thread
*
thread
,
int
pass_fd
)
{
...
...
@@ -103,7 +93,7 @@ void set_reply_fd( struct thread *thread, int pass_fd )
/* send a reply to a thread */
void
send_reply
(
struct
thread
*
thread
)
{
if
(
thread
->
state
==
SLEEPING
)
thread
->
state
=
RUNNING
;
assert
(
!
thread
->
wait
)
;
if
(
debug_level
)
trace_reply
(
thread
);
if
(
!
write_request
(
thread
))
set_select_events
(
&
thread
->
obj
,
POLLOUT
);
}
...
...
server/request.h
View file @
9de03f4f
...
...
@@ -29,12 +29,10 @@
extern
void
read_request
(
struct
thread
*
thread
);
extern
int
write_request
(
struct
thread
*
thread
);
extern
void
fatal_protocol_error
(
struct
thread
*
thread
,
const
char
*
err
,
...
);
extern
void
call_timeout_handler
(
void
*
thread
);
extern
void
set_reply_fd
(
struct
thread
*
thread
,
int
pass_fd
);
extern
void
send_reply
(
struct
thread
*
thread
);
extern
void
trace_request
(
enum
request
req
,
int
fd
);
extern
void
trace_timeout
(
void
);
extern
void
trace_kill
(
struct
thread
*
thread
);
extern
void
trace_reply
(
struct
thread
*
thread
);
...
...
server/thread.c
View file @
9de03f4f
...
...
@@ -46,6 +46,7 @@ struct thread_wait
int
flags
;
struct
timeval
timeout
;
struct
timeout_user
*
user
;
sleep_reply
reply
;
/* function to build the reply */
struct
wait_queue_entry
queues
[
1
];
};
...
...
@@ -117,8 +118,6 @@ static struct thread *create_thread( int fd, struct process *process, int suspen
thread
->
teb
=
NULL
;
thread
->
mutex
=
NULL
;
thread
->
debug_ctx
=
NULL
;
thread
->
debug_event
=
NULL
;
thread
->
exit_event
=
NULL
;
thread
->
wait
=
NULL
;
thread
->
apc
=
NULL
;
thread
->
apc_count
=
0
;
...
...
@@ -330,24 +329,19 @@ static void end_wait( struct thread *thread )
}
/* build the thread wait structure */
static
int
wait_on
(
struct
thread
*
thread
,
int
count
,
int
*
handles
,
int
flags
,
int
timeout
)
static
int
wait_on
(
int
count
,
struct
object
*
objects
[],
int
flags
,
int
timeout
,
sleep_reply
func
)
{
struct
thread_wait
*
wait
;
struct
wait_queue_entry
*
entry
;
struct
object
*
obj
;
int
i
;
if
((
count
<
0
)
||
(
count
>
MAXIMUM_WAIT_OBJECTS
))
{
set_error
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
(
wait
=
mem_alloc
(
sizeof
(
*
wait
)
+
(
count
-
1
)
*
sizeof
(
*
entry
)
)))
return
0
;
thread
->
wait
=
wait
;
current
->
wait
=
wait
;
wait
->
count
=
count
;
wait
->
flags
=
flags
;
wait
->
user
=
NULL
;
wait
->
reply
=
func
;
if
(
flags
&
SELECT_TIMEOUT
)
{
gettimeofday
(
&
wait
->
timeout
,
0
);
...
...
@@ -356,33 +350,27 @@ static int wait_on( struct thread *thread, int count,
for
(
i
=
0
,
entry
=
wait
->
queues
;
i
<
count
;
i
++
,
entry
++
)
{
if
(
!
(
obj
=
get_handle_obj
(
thread
->
process
,
handles
[
i
],
SYNCHRONIZE
,
NULL
)))
{
wait
->
count
=
i
-
1
;
end_wait
(
thread
);
return
0
;
}
entry
->
thread
=
thread
;
struct
object
*
obj
=
objects
[
i
];
entry
->
thread
=
current
;
if
(
!
obj
->
ops
->
add_queue
(
obj
,
entry
))
{
wait
->
count
=
i
-
1
;
end_wait
(
thread
);
wait
->
count
=
i
;
end_wait
(
current
);
return
0
;
}
release_object
(
obj
);
}
return
1
;
}
/* check if the thread waiting condition is satisfied */
static
int
check_wait
(
struct
thread
*
thread
,
int
*
signaled
)
static
int
check_wait
(
struct
thread
*
thread
,
struct
object
**
object
)
{
int
i
;
int
i
,
signaled
;
struct
thread_wait
*
wait
=
thread
->
wait
;
struct
wait_queue_entry
*
entry
=
wait
->
queues
;
assert
(
wait
);
*
object
=
NULL
;
if
(
wait
->
flags
&
SELECT_ALL
)
{
int
not_ok
=
0
;
...
...
@@ -392,11 +380,11 @@ static int check_wait( struct thread *thread, int *signaled )
not_ok
|=
!
entry
->
obj
->
ops
->
signaled
(
entry
->
obj
,
thread
);
if
(
not_ok
)
goto
other_checks
;
/* Wait satisfied: tell it to all objects */
*
signaled
=
0
;
signaled
=
0
;
for
(
i
=
0
,
entry
=
wait
->
queues
;
i
<
wait
->
count
;
i
++
,
entry
++
)
if
(
entry
->
obj
->
ops
->
satisfied
(
entry
->
obj
,
thread
))
*
signaled
=
STATUS_ABANDONED_WAIT_0
;
return
1
;
signaled
=
STATUS_ABANDONED_WAIT_0
;
return
signaled
;
}
else
{
...
...
@@ -404,75 +392,97 @@ static int check_wait( struct thread *thread, int *signaled )
{
if
(
!
entry
->
obj
->
ops
->
signaled
(
entry
->
obj
,
thread
))
continue
;
/* Wait satisfied: tell it to the object */
*
signaled
=
i
;
signaled
=
i
;
*
object
=
entry
->
obj
;
if
(
entry
->
obj
->
ops
->
satisfied
(
entry
->
obj
,
thread
))
*
signaled
=
i
+
STATUS_ABANDONED_WAIT_0
;
return
1
;
signaled
=
i
+
STATUS_ABANDONED_WAIT_0
;
return
signaled
;
}
}
other_checks:
if
((
wait
->
flags
&
SELECT_ALERTABLE
)
&&
thread
->
apc
)
{
*
signaled
=
STATUS_USER_APC
;
return
1
;
}
if
((
wait
->
flags
&
SELECT_ALERTABLE
)
&&
thread
->
apc
)
return
STATUS_USER_APC
;
if
(
wait
->
flags
&
SELECT_TIMEOUT
)
{
struct
timeval
now
;
gettimeofday
(
&
now
,
NULL
);
if
(
!
time_before
(
&
now
,
&
wait
->
timeout
))
{
*
signaled
=
STATUS_TIMEOUT
;
return
1
;
}
if
(
!
time_before
(
&
now
,
&
wait
->
timeout
))
return
STATUS_TIMEOUT
;
}
return
0
;
return
-
1
;
}
/* build a reply to the select request */
static
void
build_select_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
{
struct
select_request
*
req
=
get_req_ptr
(
thread
);
req
->
signaled
=
signaled
;
}
/* attempt to wake up a thread */
/* return 1 if OK, 0 if the wait condition is still not satisfied */
static
int
wake_thread
(
struct
thread
*
thread
)
{
struct
select_request
*
req
=
get_req_ptr
(
thread
);
if
(
!
check_wait
(
thread
,
&
req
->
signaled
))
return
0
;
int
signaled
;
struct
object
*
object
;
if
((
signaled
=
check_wait
(
thread
,
&
object
))
==
-
1
)
return
0
;
thread
->
error
=
0
;
thread
->
wait
->
reply
(
thread
,
object
,
signaled
);
end_wait
(
thread
);
return
1
;
}
/* thread wait timeout */
static
void
thread_timeout
(
void
*
ptr
)
{
struct
thread
*
thread
=
ptr
;
if
(
debug_level
)
fprintf
(
stderr
,
"%08x: *timeout*
\n
"
,
(
unsigned
int
)
thread
);
assert
(
thread
->
wait
);
thread
->
error
=
0
;
thread
->
wait
->
user
=
NULL
;
thread
->
wait
->
reply
(
thread
,
NULL
,
STATUS_TIMEOUT
);
end_wait
(
thread
);
send_reply
(
thread
);
}
/* sleep on a list of objects */
static
void
sleep_on
(
struct
thread
*
thread
,
int
count
,
int
*
handles
,
int
flags
,
int
timeout
)
int
sleep_on
(
int
count
,
struct
object
*
objects
[],
int
flags
,
int
timeout
,
sleep_reply
func
)
{
struct
select_request
*
req
;
assert
(
!
thread
->
wait
);
if
(
!
wait_on
(
thread
,
count
,
handles
,
flags
,
timeout
))
goto
error
;
if
(
wake_thread
(
thread
))
return
;
assert
(
!
current
->
wait
);
if
(
!
wait_on
(
count
,
objects
,
flags
,
timeout
,
func
))
return
0
;
if
(
wake_thread
(
current
))
return
1
;
/* now we need to wait */
if
(
flags
&
SELECT_TIMEOUT
)
{
if
(
!
(
thread
->
wait
->
user
=
add_timeout_user
(
&
thread
->
wait
->
timeout
,
call_timeout_handler
,
thread
)))
goto
error
;
if
(
!
(
current
->
wait
->
user
=
add_timeout_user
(
&
current
->
wait
->
timeout
,
thread_timeout
,
current
)))
{
end_wait
(
current
);
return
0
;
}
}
thread
->
state
=
SLEEPING
;
return
;
error:
req
=
get_req_ptr
(
thread
);
req
->
signaled
=
-
1
;
return
1
;
}
/*
timeout for the current thread
*/
void
thread_timeout
(
void
)
/*
select on a list of handles
*/
static
int
select_on
(
int
count
,
int
*
handles
,
int
flags
,
int
timeout
)
{
struct
select_request
*
req
=
get_req_ptr
(
current
);
int
ret
=
0
;
int
i
;
struct
object
*
objects
[
MAXIMUM_WAIT_OBJECTS
];
assert
(
current
->
wait
);
current
->
wait
->
user
=
NULL
;
end_wait
(
current
);
req
->
signaled
=
STATUS_TIMEOUT
;
send_reply
(
current
);
if
((
count
<
0
)
||
(
count
>
MAXIMUM_WAIT_OBJECTS
))
{
set_error
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
!
(
objects
[
i
]
=
get_handle_obj
(
current
->
process
,
handles
[
i
],
SYNCHRONIZE
,
NULL
)))
break
;
}
if
(
i
==
count
)
ret
=
sleep_on
(
count
,
objects
,
flags
,
timeout
,
build_select_reply
);
while
(
--
i
>=
0
)
release_object
(
objects
[
i
]
);
return
ret
;
}
/* attempt to wake threads sleeping on the object wait queue */
...
...
@@ -642,7 +652,8 @@ DECL_HANDLER(resume_thread)
/* select on a handle list */
DECL_HANDLER
(
select
)
{
sleep_on
(
current
,
req
->
count
,
req
->
handles
,
req
->
flags
,
req
->
timeout
);
if
(
!
select_on
(
req
->
count
,
req
->
handles
,
req
->
flags
,
req
->
timeout
))
req
->
signaled
=
-
1
;
}
/* queue an APC for a thread */
...
...
server/thread.h
View file @
9de03f4f
...
...
@@ -20,12 +20,10 @@ struct thread_wait;
struct
thread_apc
;
struct
mutex
;
struct
debug_ctx
;
struct
debug_event
;
enum
run_state
{
RUNNING
,
/* running normally */
SLEEPING
,
/* sleeping waiting for a request to terminate */
TERMINATED
/* terminated */
};
...
...
@@ -40,8 +38,6 @@ struct thread
struct
process
*
process
;
struct
mutex
*
mutex
;
/* list of currently owned mutexes */
struct
debug_ctx
*
debug_ctx
;
/* debugger context if this thread is a debugger */
struct
debug_event
*
debug_event
;
/* pending debug event for this thread */
struct
debug_event
*
exit_event
;
/* pending debug exit event for this thread */
struct
thread_wait
*
wait
;
/* current wait condition if sleeping */
struct
thread_apc
*
apc
;
/* list of async procedure calls */
int
apc_count
;
/* number of outstanding APCs */
...
...
@@ -59,6 +55,9 @@ struct thread
enum
request
last_req
;
/* last request received (for debugging) */
};
/* callback function for building the thread reply when sleep_on is finished */
typedef
void
(
*
sleep_reply
)(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
);
extern
struct
thread
*
current
;
/* thread functions */
...
...
@@ -74,8 +73,9 @@ extern void resume_all_threads( void );
extern
int
add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
extern
void
remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
extern
void
kill_thread
(
struct
thread
*
thread
,
int
exit_code
);
extern
void
thread_timeout
(
void
);
extern
void
wake_up
(
struct
object
*
obj
,
int
max
);
extern
int
sleep_on
(
int
count
,
struct
object
*
objects
[],
int
flags
,
int
timeout
,
sleep_reply
func
);
/* ptrace functions */
...
...
server/trace.c
View file @
9de03f4f
...
...
@@ -1336,11 +1336,6 @@ void trace_request( enum request req, int fd )
else
fprintf
(
stderr
,
" )
\n
"
);
}
void
trace_timeout
(
void
)
{
fprintf
(
stderr
,
"%08x: *timeout*
\n
"
,
(
unsigned
int
)
current
);
}
void
trace_kill
(
struct
thread
*
thread
)
{
fprintf
(
stderr
,
"%08x: *killed* exit_code=%d
\n
"
,
...
...
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