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
947e3374
Commit
947e3374
authored
Aug 22, 2013
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Make signal and wait a separate select operation.
parent
042e0046
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
86 additions
and
57 deletions
+86
-57
critsection.c
dlls/ntdll/critsection.c
+1
-1
exception.c
dlls/ntdll/exception.c
+2
-2
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-2
sync.c
dlls/ntdll/sync.c
+12
-8
server_protocol.h
include/wine/server_protocol.h
+11
-4
protocol.def
server/protocol.def
+9
-3
request.h
server/request.h
+2
-3
thread.c
server/thread.c
+42
-32
trace.c
server/trace.c
+5
-2
No files found.
dlls/ntdll/critsection.c
View file @
947e3374
...
...
@@ -235,7 +235,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
time
.
QuadPart
=
timeout
*
(
LONGLONG
)
-
10000000
;
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
handles
[
0
]
=
wine_server_obj_handle
(
sem
);
ret
=
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
0
,
&
time
,
0
);
ret
=
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
0
,
&
time
);
}
return
ret
;
}
...
...
dlls/ntdll/exception.c
View file @
947e3374
...
...
@@ -81,7 +81,7 @@ void wait_suspend( CONTEXT *context )
/* wait with 0 timeout, will only return once the thread is no longer suspended */
timeout
.
QuadPart
=
0
;
NTDLL_wait_for_multiple_objects
(
NULL
,
0
,
SELECT_INTERRUPTIBLE
,
&
timeout
,
0
);
NTDLL_wait_for_multiple_objects
(
NULL
,
0
,
SELECT_INTERRUPTIBLE
,
&
timeout
);
/* retrieve the new context */
SERVER_START_REQ
(
get_suspend_context
)
...
...
@@ -134,7 +134,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
handles
[
0
]
=
handle
;
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
SELECT_INTERRUPTIBLE
,
NULL
,
0
);
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
SELECT_INTERRUPTIBLE
,
NULL
);
SERVER_START_REQ
(
get_exception_status
)
{
...
...
dlls/ntdll/ntdll_misc.h
View file @
947e3374
...
...
@@ -63,8 +63,8 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
extern
LPCSTR
debugstr_ObjectAttributes
(
const
OBJECT_ATTRIBUTES
*
oa
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
NTDLL_queue_process_apc
(
HANDLE
process
,
const
apc_call_t
*
call
,
apc_result_t
*
result
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
NTDLL_wait_for_multiple_objects
(
const
select_op_t
*
select_op
,
data_size_t
size
,
UINT
flags
,
const
LARGE_INTEGER
*
timeout
,
HANDLE
signal_objec
t
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
NTDLL_wait_for_multiple_objects
(
const
select_op_t
*
select_op
,
data_size_t
size
,
UINT
flags
,
const
LARGE_INTEGER
*
timeou
t
)
DECLSPEC_HIDDEN
;
/* init routines */
extern
NTSTATUS
signal_alloc_thread
(
TEB
**
teb
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/sync.c
View file @
947e3374
...
...
@@ -1107,7 +1107,7 @@ NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_re
* Implementation of NtWaitForMultipleObjects
*/
NTSTATUS
NTDLL_wait_for_multiple_objects
(
const
select_op_t
*
select_op
,
data_size_t
size
,
UINT
flags
,
const
LARGE_INTEGER
*
timeout
,
HANDLE
signal_object
)
const
LARGE_INTEGER
*
timeout
)
{
NTSTATUS
ret
;
int
cookie
;
...
...
@@ -1125,7 +1125,6 @@ NTSTATUS NTDLL_wait_for_multiple_objects( const select_op_t *select_op, data_siz
{
req
->
flags
=
flags
;
req
->
cookie
=
wine_server_client_ptr
(
&
cookie
);
req
->
signal
=
wine_server_obj_handle
(
signal_object
);
req
->
prev_apc
=
apc_handle
;
req
->
timeout
=
abs_timeout
;
wine_server_add_data
(
req
,
&
result
,
sizeof
(
result
)
);
...
...
@@ -1145,7 +1144,10 @@ NTSTATUS NTDLL_wait_for_multiple_objects( const select_op_t *select_op, data_siz
abs_timeout
=
0
;
user_apc
=
TRUE
;
}
signal_object
=
0
;
/* don't signal it multiple times */
/* don't signal multiple times */
if
(
size
>=
sizeof
(
select_op
->
signal_and_wait
)
&&
select_op
->
op
==
SELECT_SIGNAL_AND_WAIT
)
size
=
offsetof
(
select_op_t
,
signal_and_wait
.
signal
);
}
if
(
ret
==
STATUS_TIMEOUT
&&
user_apc
)
ret
=
STATUS_USER_APC
;
...
...
@@ -1176,7 +1178,7 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
select_op
.
wait
.
op
=
wait_all
?
SELECT_WAIT_ALL
:
SELECT_WAIT
;
for
(
i
=
0
;
i
<
count
;
i
++
)
select_op
.
wait
.
handles
[
i
]
=
wine_server_obj_handle
(
handles
[
i
]
);
return
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
count
]
),
flags
,
timeout
,
0
);
return
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
count
]
),
flags
,
timeout
);
}
...
...
@@ -1199,10 +1201,12 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWa
UINT
flags
=
SELECT_INTERRUPTIBLE
;
if
(
!
hSignalObject
)
return
STATUS_INVALID_HANDLE
;
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
handles
[
0
]
=
wine_server_obj_handle
(
hWaitObject
);
return
NTDLL_wait_for_multiple_objects
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
flags
,
timeout
,
hSignalObject
);
select_op
.
signal_and_wait
.
op
=
SELECT_SIGNAL_AND_WAIT
;
select_op
.
signal_and_wait
.
wait
=
wine_server_obj_handle
(
hWaitObject
);
select_op
.
signal_and_wait
.
signal
=
wine_server_obj_handle
(
hSignalObject
);
return
NTDLL_wait_for_multiple_objects
(
&
select_op
,
sizeof
(
select_op
.
signal_and_wait
),
flags
,
timeout
);
}
...
...
@@ -1228,7 +1232,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
/* if alertable, we need to query the server */
if
(
alertable
)
return
NTDLL_wait_for_multiple_objects
(
NULL
,
0
,
SELECT_INTERRUPTIBLE
|
SELECT_ALERTABLE
,
timeout
,
0
);
timeout
);
if
(
!
timeout
||
timeout
->
QuadPart
==
TIMEOUT_INFINITE
)
/* sleep forever */
{
...
...
include/wine/server_protocol.h
View file @
947e3374
...
...
@@ -408,7 +408,8 @@ enum select_op
{
SELECT_NONE
,
SELECT_WAIT
,
SELECT_WAIT_ALL
SELECT_WAIT_ALL
,
SELECT_SIGNAL_AND_WAIT
};
typedef
union
...
...
@@ -419,6 +420,12 @@ typedef union
enum
select_op
op
;
obj_handle_t
handles
[
MAXIMUM_WAIT_OBJECTS
];
}
wait
;
struct
{
enum
select_op
op
;
obj_handle_t
wait
;
obj_handle_t
signal
;
}
signal_and_wait
;
}
select_op_t
;
enum
apc_type
...
...
@@ -1069,11 +1076,11 @@ struct select_request
struct
request_header
__header
;
int
flags
;
client_ptr_t
cookie
;
obj_handle_t
signal
;
obj_handle_t
prev_apc
;
timeout_t
timeout
;
obj_handle_t
prev_apc
;
/* VARARG(result,apc_result); */
/* VARARG(data,select_op); */
char
__pad_36
[
4
];
};
struct
select_reply
{
...
...
@@ -5787,6 +5794,6 @@ union generic_reply
struct
set_suspend_context_reply
set_suspend_context_reply
;
};
#define SERVER_PROTOCOL_VERSION 44
5
#define SERVER_PROTOCOL_VERSION 44
6
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
947e3374
...
...
@@ -424,7 +424,8 @@ enum select_op
{
SELECT_NONE,
SELECT_WAIT,
SELECT_WAIT_ALL
SELECT_WAIT_ALL,
SELECT_SIGNAL_AND_WAIT
};
typedef union
...
...
@@ -435,6 +436,12 @@ typedef union
enum select_op op; /* SELECT_WAIT or SELECT_WAIT_ALL */
obj_handle_t handles[MAXIMUM_WAIT_OBJECTS];
} wait;
struct
{
enum select_op op; /* SELECT_SIGNAL_AND_WAIT */
obj_handle_t wait;
obj_handle_t signal; /* must be last in the structure so we can remove it on retries */
} signal_and_wait;
} select_op_t;
enum apc_type
...
...
@@ -937,9 +944,8 @@ struct rawinput_device
@REQ(select)
int flags; /* wait flags (see below) */
client_ptr_t cookie; /* magic cookie to return to client */
obj_handle_t signal; /* object to signal (0 if none) */
obj_handle_t prev_apc; /* handle to previous APC */
timeout_t timeout; /* timeout */
obj_handle_t prev_apc; /* handle to previous APC */
VARARG(result,apc_result); /* result of previous APC */
VARARG(data,select_op); /* operation-specific data */
@REPLY
...
...
server/request.h
View file @
947e3374
...
...
@@ -816,9 +816,8 @@ C_ASSERT( FIELD_OFFSET(struct open_thread_reply, handle) == 8 );
C_ASSERT
(
sizeof
(
struct
open_thread_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
flags
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
cookie
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
signal
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
prev_apc
)
==
28
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
timeout
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
timeout
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
prev_apc
)
==
32
);
C_ASSERT
(
sizeof
(
struct
select_request
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
timeout
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
call
)
==
16
);
...
...
server/thread.c
View file @
947e3374
...
...
@@ -590,6 +590,25 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
return
1
;
}
static
int
wait_on_handles
(
const
select_op_t
*
select_op
,
unsigned
int
count
,
const
obj_handle_t
*
handles
,
int
flags
,
timeout_t
timeout
)
{
struct
object
*
objects
[
MAXIMUM_WAIT_OBJECTS
];
unsigned
int
i
;
int
ret
=
0
;
assert
(
count
<=
MAXIMUM_WAIT_OBJECTS
);
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
!
(
objects
[
i
]
=
get_handle_obj
(
current
->
process
,
handles
[
i
],
SYNCHRONIZE
,
NULL
)))
break
;
if
(
i
==
count
)
ret
=
wait_on
(
select_op
,
count
,
objects
,
flags
,
timeout
);
while
(
i
>
0
)
release_object
(
objects
[
--
i
]
);
return
ret
;
}
/* check if the thread waiting condition is satisfied */
static
int
check_wait
(
struct
thread
*
thread
)
{
...
...
@@ -714,18 +733,17 @@ static int signal_object( obj_handle_t handle )
/* select on a list of handles */
static
timeout_t
select_on
(
const
select_op_t
*
select_op
,
data_size_t
op_size
,
client_ptr_t
cookie
,
int
flags
,
timeout_t
timeout
,
obj_handle_t
signal_obj
)
int
flags
,
timeout_t
timeout
)
{
int
ret
;
unsigned
int
i
,
count
;
struct
object
*
objects
[
MAXIMUM_WAIT_OBJECTS
];
unsigned
int
count
;
if
(
timeout
<=
0
)
timeout
=
current_time
-
timeout
;
switch
(
select_op
->
op
)
{
case
SELECT_NONE
:
count
=
0
;
if
(
!
wait_on
(
select_op
,
0
,
NULL
,
flags
,
timeout
))
return
timeout
;
break
;
case
SELECT_WAIT
:
...
...
@@ -736,6 +754,23 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
set_error
(
STATUS_INVALID_PARAMETER
);
return
0
;
}
if
(
!
wait_on_handles
(
select_op
,
count
,
select_op
->
wait
.
handles
,
flags
,
timeout
))
return
timeout
;
break
;
case
SELECT_SIGNAL_AND_WAIT
:
if
(
!
wait_on_handles
(
select_op
,
1
,
&
select_op
->
signal_and_wait
.
wait
,
flags
,
timeout
))
return
timeout
;
if
(
select_op
->
signal_and_wait
.
signal
)
{
if
(
!
signal_object
(
select_op
->
signal_and_wait
.
signal
))
{
end_wait
(
current
);
return
timeout
;
}
/* check if we woke ourselves up */
if
(
!
current
->
wait
)
return
timeout
;
}
break
;
default:
...
...
@@ -743,34 +778,12 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
return
0
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
!
(
objects
[
i
]
=
get_handle_obj
(
current
->
process
,
select_op
->
wait
.
handles
[
i
],
SYNCHRONIZE
,
NULL
)))
break
;
}
if
(
i
<
count
)
goto
done
;
if
(
!
wait_on
(
select_op
,
count
,
objects
,
flags
,
timeout
))
goto
done
;
/* signal the object */
if
(
signal_obj
)
{
if
(
!
signal_object
(
signal_obj
))
{
end_wait
(
current
);
goto
done
;
}
/* check if we woke ourselves up */
if
(
!
current
->
wait
)
goto
done
;
}
if
((
ret
=
check_wait
(
current
))
!=
-
1
)
{
/* condition is already satisfied */
end_wait
(
current
);
set_error
(
ret
);
goto
done
;
return
timeout
;
}
/* now we need to wait */
...
...
@@ -780,14 +793,11 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
thread_timeout
,
current
->
wait
)))
{
end_wait
(
current
);
goto
done
;
return
timeout
;
}
}
current
->
wait
->
cookie
=
cookie
;
set_error
(
STATUS_PENDING
);
done:
while
(
i
>
0
)
release_object
(
objects
[
--
i
]
);
return
timeout
;
}
...
...
@@ -1370,7 +1380,7 @@ DECL_HANDLER(select)
release_object
(
apc
);
}
reply
->
timeout
=
select_on
(
&
select_op
,
op_size
,
req
->
cookie
,
req
->
flags
,
req
->
timeout
,
req
->
signal
);
reply
->
timeout
=
select_on
(
&
select_op
,
op_size
,
req
->
cookie
,
req
->
flags
,
req
->
timeout
);
if
(
get_error
()
==
STATUS_USER_APC
)
{
...
...
server/trace.c
View file @
947e3374
...
...
@@ -405,6 +405,10 @@ static void dump_varargs_select_op( const char *prefix, data_size_t size )
dump_handles
(
",handles="
,
data
.
wait
.
handles
,
min
(
size
,
sizeof
(
data
.
wait
)
)
-
offsetof
(
select_op_t
,
wait
.
handles
));
break
;
case
SELECT_SIGNAL_AND_WAIT
:
fprintf
(
stderr
,
"SIGNAL_AND_WAIT,signal=%04x,wait=%04x"
,
data
.
signal_and_wait
.
signal
,
data
.
signal_and_wait
.
wait
);
break
;
default:
fprintf
(
stderr
,
"op=%u"
,
data
.
op
);
break
;
...
...
@@ -1388,9 +1392,8 @@ static void dump_select_request( const struct select_request *req )
{
fprintf
(
stderr
,
" flags=%d"
,
req
->
flags
);
dump_uint64
(
", cookie="
,
&
req
->
cookie
);
fprintf
(
stderr
,
", signal=%04x"
,
req
->
signal
);
fprintf
(
stderr
,
", prev_apc=%04x"
,
req
->
prev_apc
);
dump_timeout
(
", timeout="
,
&
req
->
timeout
);
fprintf
(
stderr
,
", prev_apc=%04x"
,
req
->
prev_apc
);
dump_varargs_apc_result
(
", result="
,
cur_size
);
dump_varargs_select_op
(
", data="
,
cur_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