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
93fbb12e
Commit
93fbb12e
authored
Aug 22, 2013
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Implement waiting on keyed events.
parent
d4cd051c
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
130 additions
and
12 deletions
+130
-12
sync.c
dlls/ntdll/sync.c
+18
-4
server_protocol.h
include/wine/server_protocol.h
+10
-2
event.c
server/event.c
+28
-5
object.h
server/object.h
+5
-0
protocol.def
server/protocol.def
+9
-1
thread.c
server/thread.c
+50
-0
thread.h
server/thread.h
+3
-0
trace.c
server/trace.c
+7
-0
No files found.
dlls/ntdll/sync.c
View file @
93fbb12e
...
...
@@ -985,8 +985,15 @@ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJE
NTSTATUS
WINAPI
NtWaitForKeyedEvent
(
HANDLE
handle
,
const
void
*
key
,
BOOLEAN
alertable
,
const
LARGE_INTEGER
*
timeout
)
{
FIXME
(
"stub
\n
"
);
return
STATUS_NOT_IMPLEMENTED
;
select_op_t
select_op
;
UINT
flags
=
SELECT_INTERRUPTIBLE
;
if
((
ULONG_PTR
)
key
&
1
)
return
STATUS_INVALID_PARAMETER_1
;
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
select_op
.
keyed_event
.
op
=
SELECT_KEYED_EVENT_WAIT
;
select_op
.
keyed_event
.
handle
=
wine_server_obj_handle
(
handle
);
select_op
.
keyed_event
.
key
=
wine_server_client_ptr
(
key
);
return
server_select
(
&
select_op
,
sizeof
(
select_op
.
keyed_event
),
flags
,
timeout
);
}
/******************************************************************************
...
...
@@ -995,8 +1002,15 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
NTSTATUS
WINAPI
NtReleaseKeyedEvent
(
HANDLE
handle
,
const
void
*
key
,
BOOLEAN
alertable
,
const
LARGE_INTEGER
*
timeout
)
{
FIXME
(
"stub
\n
"
);
return
STATUS_NOT_IMPLEMENTED
;
select_op_t
select_op
;
UINT
flags
=
SELECT_INTERRUPTIBLE
;
if
((
ULONG_PTR
)
key
&
1
)
return
STATUS_INVALID_PARAMETER_1
;
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
select_op
.
keyed_event
.
op
=
SELECT_KEYED_EVENT_RELEASE
;
select_op
.
keyed_event
.
handle
=
wine_server_obj_handle
(
handle
);
select_op
.
keyed_event
.
key
=
wine_server_client_ptr
(
key
);
return
server_select
(
&
select_op
,
sizeof
(
select_op
.
keyed_event
),
flags
,
timeout
);
}
/******************************************************************
...
...
include/wine/server_protocol.h
View file @
93fbb12e
...
...
@@ -409,7 +409,9 @@ enum select_op
SELECT_NONE
,
SELECT_WAIT
,
SELECT_WAIT_ALL
,
SELECT_SIGNAL_AND_WAIT
SELECT_SIGNAL_AND_WAIT
,
SELECT_KEYED_EVENT_WAIT
,
SELECT_KEYED_EVENT_RELEASE
};
typedef
union
...
...
@@ -426,6 +428,12 @@ typedef union
obj_handle_t
wait
;
obj_handle_t
signal
;
}
signal_and_wait
;
struct
{
enum
select_op
op
;
obj_handle_t
handle
;
client_ptr_t
key
;
}
keyed_event
;
}
select_op_t
;
enum
apc_type
...
...
@@ -5794,6 +5802,6 @@ union generic_reply
struct
set_suspend_context_reply
set_suspend_context_reply
;
};
#define SERVER_PROTOCOL_VERSION 44
6
#define SERVER_PROTOCOL_VERSION 44
7
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/event.c
View file @
93fbb12e
...
...
@@ -101,10 +101,6 @@ static const struct object_ops keyed_event_ops =
no_destroy
/* destroy */
};
#define KEYEDEVENT_WAIT 0x0001
#define KEYEDEVENT_WAKE 0x0002
#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
struct
event
*
create_event
(
struct
directory
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
int
manual_reset
,
int
initial_state
,
...
...
@@ -227,6 +223,11 @@ struct keyed_event *create_keyed_event( struct directory *root, const struct uni
return
event
;
}
struct
keyed_event
*
get_keyed_event_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
)
{
return
(
struct
keyed_event
*
)
get_handle_obj
(
process
,
handle
,
access
,
&
keyed_event_ops
);
}
static
void
keyed_event_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
keyed_event
*
event
=
(
struct
keyed_event
*
)
obj
;
...
...
@@ -243,10 +244,32 @@ static struct object_type *keyed_event_get_type( struct object *obj )
return
get_object_type
(
&
str
);
}
static
enum
select_op
matching_op
(
enum
select_op
op
)
{
return
op
^
(
SELECT_KEYED_EVENT_WAIT
^
SELECT_KEYED_EVENT_RELEASE
);
}
static
int
keyed_event_signaled
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
{
struct
wait_queue_entry
*
ptr
;
struct
process
*
process
;
enum
select_op
select_op
;
assert
(
obj
->
ops
==
&
keyed_event_ops
);
return
1
;
process
=
get_wait_queue_thread
(
entry
)
->
process
;
select_op
=
get_wait_queue_select_op
(
entry
);
if
(
select_op
!=
SELECT_KEYED_EVENT_WAIT
&&
select_op
!=
SELECT_KEYED_EVENT_RELEASE
)
return
1
;
LIST_FOR_EACH_ENTRY
(
ptr
,
&
obj
->
wait_queue
,
struct
wait_queue_entry
,
entry
)
{
if
(
ptr
==
entry
)
continue
;
if
(
get_wait_queue_thread
(
ptr
)
->
process
!=
process
)
continue
;
if
(
get_wait_queue_select_op
(
ptr
)
!=
matching_op
(
select_op
))
continue
;
if
(
get_wait_queue_key
(
ptr
)
!=
get_wait_queue_key
(
entry
))
continue
;
if
(
wake_thread_queue_entry
(
ptr
))
return
1
;
}
return
0
;
}
static
unsigned
int
keyed_event_map_access
(
struct
object
*
obj
,
unsigned
int
access
)
...
...
server/object.h
View file @
93fbb12e
...
...
@@ -160,6 +160,7 @@ extern struct event *create_event( struct directory *root, const struct unicode_
extern
struct
keyed_event
*
create_keyed_event
(
struct
directory
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
const
struct
security_descriptor
*
sd
);
extern
struct
event
*
get_event_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
);
extern
struct
keyed_event
*
get_keyed_event_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
);
extern
void
pulse_event
(
struct
event
*
event
);
extern
void
set_event
(
struct
event
*
event
);
extern
void
reset_event
(
struct
event
*
event
);
...
...
@@ -235,4 +236,8 @@ extern const char *server_argv0;
/* server start time used for GetTickCount() */
extern
timeout_t
server_start_time
;
#define KEYEDEVENT_WAIT 0x0001
#define KEYEDEVENT_WAKE 0x0002
#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
#endif
/* __WINE_SERVER_OBJECT_H */
server/protocol.def
View file @
93fbb12e
...
...
@@ -425,7 +425,9 @@ enum select_op
SELECT_NONE,
SELECT_WAIT,
SELECT_WAIT_ALL,
SELECT_SIGNAL_AND_WAIT
SELECT_SIGNAL_AND_WAIT,
SELECT_KEYED_EVENT_WAIT,
SELECT_KEYED_EVENT_RELEASE
};
typedef union
...
...
@@ -442,6 +444,12 @@ typedef union
obj_handle_t wait;
obj_handle_t signal; /* must be last in the structure so we can remove it on retries */
} signal_and_wait;
struct
{
enum select_op op; /* SELECT_KEYED_EVENT_WAIT or SELECT_KEYED_EVENT_RELEASE */
obj_handle_t handle;
client_ptr_t key;
} keyed_event;
} select_op_t;
enum apc_type
...
...
server/thread.c
View file @
93fbb12e
...
...
@@ -77,6 +77,7 @@ struct thread_wait
int
flags
;
int
abandoned
;
enum
select_op
select
;
client_ptr_t
key
;
/* wait key for keyed events */
client_ptr_t
cookie
;
/* magic cookie to return to client */
timeout_t
timeout
;
struct
timeout_user
*
user
;
...
...
@@ -549,6 +550,16 @@ struct thread *get_wait_queue_thread( struct wait_queue_entry *entry )
return
entry
->
wait
->
thread
;
}
enum
select_op
get_wait_queue_select_op
(
struct
wait_queue_entry
*
entry
)
{
return
entry
->
wait
->
select
;
}
client_ptr_t
get_wait_queue_key
(
struct
wait_queue_entry
*
entry
)
{
return
entry
->
wait
->
key
;
}
void
make_wait_abandoned
(
struct
wait_queue_entry
*
entry
)
{
entry
->
wait
->
abandoned
=
1
;
...
...
@@ -707,6 +718,33 @@ int wake_thread( struct thread *thread )
return
count
;
}
/* attempt to wake up a thread from a wait queue entry, assuming that it is signaled */
int
wake_thread_queue_entry
(
struct
wait_queue_entry
*
entry
)
{
struct
thread_wait
*
wait
=
entry
->
wait
;
struct
thread
*
thread
=
wait
->
thread
;
int
signaled
;
client_ptr_t
cookie
;
if
(
thread
->
wait
!=
wait
)
return
0
;
/* not the current wait */
if
(
thread
->
process
->
suspend
+
thread
->
suspend
>
0
)
return
0
;
/* cannot acquire locks */
assert
(
wait
->
select
!=
SELECT_WAIT_ALL
);
signaled
=
entry
-
wait
->
queues
;
entry
->
obj
->
ops
->
satisfied
(
entry
->
obj
,
entry
);
if
(
wait
->
abandoned
)
signaled
+=
STATUS_ABANDONED_WAIT_0
;
cookie
=
wait
->
cookie
;
if
(
debug_level
)
fprintf
(
stderr
,
"%04x: *wakeup* signaled=%d
\n
"
,
thread
->
id
,
signaled
);
end_wait
(
thread
);
if
(
send_thread_wakeup
(
thread
,
cookie
,
signaled
)
!=
-
1
)
wake_thread
(
thread
);
/* check other waits too */
return
1
;
}
/* thread wait timeout */
static
void
thread_timeout
(
void
*
ptr
)
{
...
...
@@ -746,6 +784,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
{
int
ret
;
unsigned
int
count
;
struct
object
*
object
;
if
(
timeout
<=
0
)
timeout
=
current_time
-
timeout
;
...
...
@@ -782,6 +821,17 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
}
break
;
case
SELECT_KEYED_EVENT_WAIT
:
case
SELECT_KEYED_EVENT_RELEASE
:
object
=
(
struct
object
*
)
get_keyed_event_obj
(
current
->
process
,
select_op
->
keyed_event
.
handle
,
select_op
->
op
==
SELECT_KEYED_EVENT_WAIT
?
KEYEDEVENT_WAIT
:
KEYEDEVENT_WAKE
);
if
(
!
object
)
return
timeout
;
ret
=
wait_on
(
select_op
,
1
,
&
object
,
flags
,
timeout
);
release_object
(
object
);
if
(
!
ret
)
return
timeout
;
current
->
wait
->
key
=
select_op
->
keyed_event
.
key
;
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
0
;
...
...
server/thread.h
View file @
93fbb12e
...
...
@@ -106,10 +106,13 @@ extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int
extern
struct
thread
*
get_thread_from_tid
(
int
tid
);
extern
struct
thread
*
get_thread_from_pid
(
int
pid
);
extern
struct
thread
*
get_wait_queue_thread
(
struct
wait_queue_entry
*
entry
);
extern
enum
select_op
get_wait_queue_select_op
(
struct
wait_queue_entry
*
entry
);
extern
client_ptr_t
get_wait_queue_key
(
struct
wait_queue_entry
*
entry
);
extern
void
make_wait_abandoned
(
struct
wait_queue_entry
*
entry
);
extern
void
stop_thread
(
struct
thread
*
thread
);
extern
void
stop_thread_if_suspended
(
struct
thread
*
thread
);
extern
int
wake_thread
(
struct
thread
*
thread
);
extern
int
wake_thread_queue_entry
(
struct
wait_queue_entry
*
entry
);
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
violent_death
);
...
...
server/trace.c
View file @
93fbb12e
...
...
@@ -409,6 +409,13 @@ static void dump_varargs_select_op( const char *prefix, data_size_t size )
fprintf
(
stderr
,
"SIGNAL_AND_WAIT,signal=%04x,wait=%04x"
,
data
.
signal_and_wait
.
signal
,
data
.
signal_and_wait
.
wait
);
break
;
case
SELECT_KEYED_EVENT_WAIT
:
case
SELECT_KEYED_EVENT_RELEASE
:
fprintf
(
stderr
,
"KEYED_EVENT_%s,handle=%04x"
,
data
.
op
==
SELECT_KEYED_EVENT_WAIT
?
"WAIT"
:
"RELEASE"
,
data
.
keyed_event
.
handle
);
dump_uint64
(
",key="
,
&
data
.
keyed_event
.
key
);
break
;
default:
fprintf
(
stderr
,
"op=%u"
,
data
.
op
);
break
;
...
...
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