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
fbef57c0
Commit
fbef57c0
authored
Mar 31, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved WaitForMultipleObjects to ntdll (based on a patch by Eric
Pouech). Added NTDLL_get_server_timeout function to compute ntdll-style timeouts and adapted the timer code to use it.
parent
43bfe7f2
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
263 additions
and
236 deletions
+263
-236
ntdll.spec
dlls/ntdll/ntdll.spec
+2
-2
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-0
om.c
dlls/ntdll/om.c
+0
-13
sync.c
dlls/ntdll/sync.c
+192
-5
time.c
dlls/ntdll/time.c
+42
-6
winternl.h
include/winternl.h
+1
-0
synchro.c
scheduler/synchro.c
+15
-188
timer.c
scheduler/timer.c
+9
-22
No files found.
dlls/ntdll/ntdll.spec
View file @
fbef57c0
...
...
@@ -249,7 +249,7 @@
@ stdcall NtUnmapViewOfSection(long ptr)
@ stub NtVdmControl
@ stub NtW32Call
@ st
ub NtWaitForMultipleObjects
@ st
dcall NtWaitForMultipleObjects(long ptr long long ptr)
@ stub NtWaitForProcessMutant
@ stdcall NtWaitForSingleObject(long long long)
@ stub NtWaitHighEventPair
...
...
@@ -773,7 +773,7 @@
@ stdcall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection
@ stub ZwVdmControl
@ stub ZwW32Call
@ st
ub Zw
WaitForMultipleObjects
@ st
dcall ZwWaitForMultipleObjects(long ptr long long ptr) Nt
WaitForMultipleObjects
@ stub ZwWaitForProcessMutant
@ stdcall ZwWaitForSingleObject(long long long) NtWaitForSingleObject
@ stub ZwWaitHighEventPair
...
...
dlls/ntdll/ntdll_misc.h
View file @
fbef57c0
...
...
@@ -28,6 +28,8 @@
extern
LPCSTR
debugstr_us
(
const
UNICODE_STRING
*
str
);
extern
void
dump_ObjectAttributes
(
const
OBJECT_ATTRIBUTES
*
ObjectAttributes
);
extern
void
NTDLL_get_server_timeout
(
struct
timeval
*
when
,
const
LARGE_INTEGER
*
timeout
);
/* module handling */
extern
FARPROC
MODULE_GetProcAddress
(
HMODULE
hModule
,
LPCSTR
function
,
int
hint
,
BOOL
snoop
);
extern
WINE_MODREF
*
MODULE_AllocModRef
(
HMODULE
hModule
,
LPCSTR
filename
);
...
...
dlls/ntdll/om.c
View file @
fbef57c0
...
...
@@ -268,19 +268,6 @@ NTSTATUS WINAPI NtClose( HANDLE Handle )
return
ret
;
}
/******************************************************************************
* NtWaitForSingleObject [NTDLL.@]
* ZwWaitForSingleObject [NTDLL.@]
*/
NTSTATUS
WINAPI
NtWaitForSingleObject
(
IN
HANDLE
Object
,
IN
BOOLEAN
Alertable
,
IN
PLARGE_INTEGER
Time
)
{
FIXME
(
"(%p,0x%08x,%p),stub!
\n
"
,
Object
,
Alertable
,
Time
);
return
0
;
}
/*
* Directory functions
*/
...
...
dlls/ntdll/sync.c
View file @
fbef57c0
/*
* Process synchronisation
*
* Copyright 1997 Alexandre Julliard
* Copyright 1999, 2000 Juergen Schmied
*
* This library is free software; you can redistribute it and/or
...
...
@@ -18,16 +19,31 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <signal.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "wine/debug.h"
#include "winerror.h"
#include "wine/unicode.h"
#include "wine/server.h"
#include "winternl.h"
#include "async.h"
#include "thread.h"
#include "wine/server.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ntdll
);
...
...
@@ -261,3 +277,174 @@ NTSTATUS WINAPI NtQueryEvent (
FIXME
(
"(%p)
\n
"
,
EventHandle
);
return
STATUS_SUCCESS
;
}
/***********************************************************************
* check_async_list
*
* Process a status event from the server.
*/
static
void
WINAPI
check_async_list
(
async_private
*
asp
,
DWORD
status
)
{
async_private
*
ovp
;
DWORD
ovp_status
;
for
(
ovp
=
NtCurrentTeb
()
->
pending_list
;
ovp
&&
ovp
!=
asp
;
ovp
=
ovp
->
next
);
if
(
!
ovp
)
return
;
if
(
status
!=
STATUS_ALERTED
)
{
ovp_status
=
status
;
ovp
->
ops
->
set_status
(
ovp
,
status
);
}
else
ovp_status
=
ovp
->
ops
->
get_status
(
ovp
);
if
(
ovp_status
==
STATUS_PENDING
)
ovp
->
func
(
ovp
);
/* This will destroy all but PENDING requests */
register_old_async
(
ovp
);
}
/***********************************************************************
* wait_reply
*
* Wait for a reply on the waiting pipe of the current thread.
*/
static
int
wait_reply
(
void
*
cookie
)
{
int
signaled
;
struct
wake_up_reply
reply
;
for
(;;)
{
int
ret
;
ret
=
read
(
NtCurrentTeb
()
->
wait_fd
[
0
],
&
reply
,
sizeof
(
reply
)
);
if
(
ret
==
sizeof
(
reply
))
{
if
(
!
reply
.
cookie
)
break
;
/* thread got killed */
if
(
reply
.
cookie
==
cookie
)
return
reply
.
signaled
;
/* we stole another reply, wait for the real one */
signaled
=
wait_reply
(
cookie
);
/* and now put the wrong one back in the pipe */
for
(;;)
{
ret
=
write
(
NtCurrentTeb
()
->
wait_fd
[
1
],
&
reply
,
sizeof
(
reply
)
);
if
(
ret
==
sizeof
(
reply
))
break
;
if
(
ret
>=
0
)
server_protocol_error
(
"partial wakeup write %d
\n
"
,
ret
);
if
(
errno
==
EINTR
)
continue
;
server_protocol_perror
(
"wakeup write"
);
}
return
signaled
;
}
if
(
ret
>=
0
)
server_protocol_error
(
"partial wakeup read %d
\n
"
,
ret
);
if
(
errno
==
EINTR
)
continue
;
server_protocol_perror
(
"wakeup read"
);
}
/* the server closed the connection; time to die... */
SYSDEPS_AbortThread
(
0
);
}
/***********************************************************************
* call_apcs
*
* Call outstanding APCs.
*/
static
void
call_apcs
(
BOOL
alertable
)
{
FARPROC
proc
=
NULL
;
LARGE_INTEGER
time
;
void
*
args
[
4
];
for
(;;)
{
int
type
=
APC_NONE
;
SERVER_START_REQ
(
get_apc
)
{
req
->
alertable
=
alertable
;
wine_server_set_reply
(
req
,
args
,
sizeof
(
args
)
);
if
(
!
wine_server_call
(
req
))
{
type
=
reply
->
type
;
proc
=
reply
->
func
;
}
}
SERVER_END_REQ
;
switch
(
type
)
{
case
APC_NONE
:
return
;
/* no more APCs */
case
APC_ASYNC
:
proc
(
args
[
0
],
args
[
1
]);
break
;
case
APC_USER
:
proc
(
args
[
0
]
);
break
;
case
APC_TIMER
:
/* convert sec/usec to NT time */
RtlSecondsSince1970ToTime
(
(
time_t
)
args
[
0
],
&
time
);
time
.
QuadPart
+=
(
DWORD
)
args
[
1
]
*
10
;
proc
(
args
[
2
],
time
.
s
.
LowPart
,
time
.
s
.
HighPart
);
break
;
case
APC_ASYNC_IO
:
check_async_list
(
args
[
0
],
(
DWORD
)
args
[
1
]);
break
;
default:
server_protocol_error
(
"get_apc_request: bad type %d
\n
"
,
type
);
break
;
}
}
}
/* wait operations */
/******************************************************************
* NtWaitForMultipleObjects (NTDLL.@)
*/
NTSTATUS
WINAPI
NtWaitForMultipleObjects
(
DWORD
count
,
const
HANDLE
*
handles
,
BOOLEAN
wait_all
,
BOOLEAN
alertable
,
PLARGE_INTEGER
timeout
)
{
int
ret
,
cookie
;
struct
timeval
tv
;
if
(
count
>
MAXIMUM_WAIT_OBJECTS
)
return
STATUS_INVALID_PARAMETER_1
;
NTDLL_get_server_timeout
(
&
tv
,
timeout
);
for
(;;)
{
SERVER_START_REQ
(
select
)
{
req
->
flags
=
SELECT_INTERRUPTIBLE
;
req
->
cookie
=
&
cookie
;
req
->
sec
=
tv
.
tv_sec
;
req
->
usec
=
tv
.
tv_usec
;
wine_server_add_data
(
req
,
handles
,
count
*
sizeof
(
HANDLE
)
);
if
(
wait_all
)
req
->
flags
|=
SELECT_ALL
;
if
(
alertable
)
req
->
flags
|=
SELECT_ALERTABLE
;
if
(
timeout
)
req
->
flags
|=
SELECT_TIMEOUT
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
==
STATUS_PENDING
)
ret
=
wait_reply
(
&
cookie
);
if
(
ret
!=
STATUS_USER_APC
)
break
;
call_apcs
(
alertable
);
if
(
alertable
)
break
;
}
return
ret
;
}
/******************************************************************
* NtWaitForSingleObject (NTDLL.@)
*/
NTSTATUS
WINAPI
NtWaitForSingleObject
(
HANDLE
handle
,
BOOLEAN
alertable
,
PLARGE_INTEGER
timeout
)
{
return
NtWaitForMultipleObjects
(
1
,
&
handle
,
FALSE
,
alertable
,
timeout
);
}
dlls/ntdll/time.c
View file @
fbef57c0
...
...
@@ -269,9 +269,11 @@ static const struct tagTZ_INFO TZ_INFO[] =
#define MONSPERYEAR 12
/* 1601 to 1970 is 369 years plus 89 leap days */
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
/* 1601 to 1980 is 379 years plus 91 leap days */
#define SECS_1601_to_1980 ((379 * 365 + 91) * (ULONGLONG)86400)
#define SECS_1601_TO_1980 ((379 * 365 + 91) * (ULONGLONG)SECSPERDAY)
#define TICKS_1601_TO_1980 (SECS_1601_TO_1980 * TICKSPERSEC)
static
const
int
YearLengths
[
2
]
=
{
DAYSPERNORMALYEAR
,
DAYSPERLEAPYEAR
};
...
...
@@ -292,6 +294,39 @@ static inline void NormalizeTimeFields(CSHORT *FieldToNormalize, CSHORT *CarryFi
*
CarryField
=
(
CSHORT
)
(
*
CarryField
+
1
);
}
/***********************************************************************
* NTDLL_get_server_timeout
*
* Convert a NTDLL timeout into a timeval struct to send to the server.
*/
void
NTDLL_get_server_timeout
(
struct
timeval
*
when
,
const
LARGE_INTEGER
*
timeout
)
{
UINT
remainder
;
if
(
!
timeout
)
/* infinite timeout */
{
when
->
tv_sec
=
when
->
tv_usec
=
0
;
}
else
if
(
timeout
->
QuadPart
<=
0
)
/* relative timeout */
{
ULONG
sec
=
RtlEnlargedUnsignedDivide
(
-
timeout
->
QuadPart
,
TICKSPERSEC
,
&
remainder
);
gettimeofday
(
when
,
0
);
if
((
when
->
tv_usec
+=
remainder
/
10
)
>=
1000000
)
{
when
->
tv_usec
-=
1000000
;
when
->
tv_sec
++
;
}
when
->
tv_sec
+=
sec
;
}
else
/* absolute time */
{
when
->
tv_sec
=
RtlEnlargedUnsignedDivide
(
timeout
->
QuadPart
-
TICKS_1601_TO_1970
,
TICKSPERSEC
,
&
remainder
);
when
->
tv_usec
=
remainder
/
10
;
}
}
/******************************************************************************
* RtlTimeToTimeFields [NTDLL.@]
*
...
...
@@ -501,7 +536,7 @@ BOOLEAN WINAPI RtlTimeToSecondsSince1980( const LARGE_INTEGER *time, LPDWORD res
{
ULONGLONG
tmp
=
((
ULONGLONG
)
time
->
s
.
HighPart
<<
32
)
|
time
->
s
.
LowPart
;
tmp
=
RtlLargeIntegerDivide
(
tmp
,
10000000
,
NULL
);
tmp
-=
SECS_1601_
to
_1980
;
tmp
-=
SECS_1601_
TO
_1980
;
if
(
tmp
>
0xffffffff
)
return
FALSE
;
*
res
=
(
DWORD
)
tmp
;
return
TRUE
;
...
...
@@ -521,7 +556,7 @@ BOOLEAN WINAPI RtlTimeToSecondsSince1980( const LARGE_INTEGER *time, LPDWORD res
*/
void
WINAPI
RtlSecondsSince1970ToTime
(
DWORD
time
,
LARGE_INTEGER
*
res
)
{
ULONGLONG
secs
=
RtlExtendedIntegerMultiply
(
time
+
SECS_1601_TO_1970
,
10000000
)
;
ULONGLONG
secs
=
time
*
(
ULONGLONG
)
TICKSPERSEC
+
TICKS_1601_TO_1970
;
res
->
s
.
LowPart
=
(
DWORD
)
secs
;
res
->
s
.
HighPart
=
(
DWORD
)(
secs
>>
32
);
}
...
...
@@ -540,7 +575,7 @@ void WINAPI RtlSecondsSince1970ToTime( DWORD time, LARGE_INTEGER *res )
*/
void
WINAPI
RtlSecondsSince1980ToTime
(
DWORD
time
,
LARGE_INTEGER
*
res
)
{
ULONGLONG
secs
=
RtlExtendedIntegerMultiply
(
time
+
SECS_1601_to_1980
,
10000000
)
;
ULONGLONG
secs
=
time
*
(
ULONGLONG
)
TICKSPERSEC
+
TICKS_1601_TO_1980
;
res
->
s
.
LowPart
=
(
DWORD
)
secs
;
res
->
s
.
HighPart
=
(
DWORD
)(
secs
>>
32
);
}
...
...
@@ -588,7 +623,8 @@ NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER time )
struct
timeval
now
;
gettimeofday
(
&
now
,
0
);
time
->
QuadPart
=
RtlExtendedIntegerMultiply
(
now
.
tv_sec
+
SECS_1601_TO_1970
,
10000000
)
+
now
.
tv_usec
*
10
;
time
->
QuadPart
=
now
.
tv_sec
*
(
ULONGLONG
)
TICKSPERSEC
+
TICKS_1601_TO_1970
;
time
->
QuadPart
+=
now
.
tv_usec
*
10
;
return
STATUS_SUCCESS
;
}
...
...
include/winternl.h
View file @
fbef57c0
...
...
@@ -872,6 +872,7 @@ NTSTATUS WINAPI NtUnloadKey(HKEY);
NTSTATUS
WINAPI
NtUnlockVirtualMemory
(
HANDLE
,
PVOID
*
,
ULONG
*
,
ULONG
);
NTSTATUS
WINAPI
NtUnmapViewOfSection
(
HANDLE
,
PVOID
);
NTSTATUS
WINAPI
NtWaitForSingleObject
(
HANDLE
,
BOOLEAN
,
PLARGE_INTEGER
);
NTSTATUS
WINAPI
NtWaitForMultipleObjects
(
ULONG
,
const
HANDLE
*
,
BOOLEAN
,
BOOLEAN
,
PLARGE_INTEGER
);
void
WINAPI
RtlAcquirePebLock
(
void
);
BYTE
WINAPI
RtlAcquireResourceExclusive
(
LPRTL_RWLOCK
,
BYTE
);
...
...
scheduler/synchro.c
View file @
fbef57c0
...
...
@@ -20,165 +20,11 @@
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <signal.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include "file.h"
/* for DOSFS_UnixTimeToFileTime */
#include "thread.h"
#include "winerror.h"
#include "wine/server.h"
#include "async.h"
/***********************************************************************
* get_timeout
*/
inline
static
void
get_timeout
(
struct
timeval
*
when
,
int
timeout
)
{
gettimeofday
(
when
,
0
);
if
(
timeout
)
{
long
sec
=
timeout
/
1000
;
if
((
when
->
tv_usec
+=
(
timeout
-
1000
*
sec
)
*
1000
)
>=
1000000
)
{
when
->
tv_usec
-=
1000000
;
when
->
tv_sec
++
;
}
when
->
tv_sec
+=
sec
;
}
}
/***********************************************************************
* check_async_list
*
* Process a status event from the server.
*/
static
void
WINAPI
check_async_list
(
async_private
*
asp
,
DWORD
status
)
{
async_private
*
ovp
;
DWORD
ovp_status
;
for
(
ovp
=
NtCurrentTeb
()
->
pending_list
;
ovp
&&
ovp
!=
asp
;
ovp
=
ovp
->
next
);
if
(
!
ovp
)
return
;
if
(
status
!=
STATUS_ALERTED
)
{
ovp_status
=
status
;
ovp
->
ops
->
set_status
(
ovp
,
status
);
}
else
ovp_status
=
ovp
->
ops
->
get_status
(
ovp
);
if
(
ovp_status
==
STATUS_PENDING
)
ovp
->
func
(
ovp
);
/* This will destroy all but PENDING requests */
register_old_async
(
ovp
);
}
/***********************************************************************
* wait_reply
*
* Wait for a reply on the waiting pipe of the current thread.
*/
static
int
wait_reply
(
void
*
cookie
)
{
int
signaled
;
struct
wake_up_reply
reply
;
for
(;;)
{
int
ret
;
ret
=
read
(
NtCurrentTeb
()
->
wait_fd
[
0
],
&
reply
,
sizeof
(
reply
)
);
if
(
ret
==
sizeof
(
reply
))
{
if
(
!
reply
.
cookie
)
break
;
/* thread got killed */
if
(
reply
.
cookie
==
cookie
)
return
reply
.
signaled
;
/* we stole another reply, wait for the real one */
signaled
=
wait_reply
(
cookie
);
/* and now put the wrong one back in the pipe */
for
(;;)
{
ret
=
write
(
NtCurrentTeb
()
->
wait_fd
[
1
],
&
reply
,
sizeof
(
reply
)
);
if
(
ret
==
sizeof
(
reply
))
break
;
if
(
ret
>=
0
)
server_protocol_error
(
"partial wakeup write %d
\n
"
,
ret
);
if
(
errno
==
EINTR
)
continue
;
server_protocol_perror
(
"wakeup write"
);
}
return
signaled
;
}
if
(
ret
>=
0
)
server_protocol_error
(
"partial wakeup read %d
\n
"
,
ret
);
if
(
errno
==
EINTR
)
continue
;
server_protocol_perror
(
"wakeup read"
);
}
/* the server closed the connection; time to die... */
SYSDEPS_AbortThread
(
0
);
}
#include "winbase.h"
#include "winternl.h"
/***********************************************************************
* call_apcs
*
* Call outstanding APCs.
*/
static
void
call_apcs
(
BOOL
alertable
)
{
FARPROC
proc
=
NULL
;
FILETIME
ft
;
void
*
args
[
4
];
for
(;;)
{
int
type
=
APC_NONE
;
SERVER_START_REQ
(
get_apc
)
{
req
->
alertable
=
alertable
;
wine_server_set_reply
(
req
,
args
,
sizeof
(
args
)
);
if
(
!
wine_server_call
(
req
))
{
type
=
reply
->
type
;
proc
=
reply
->
func
;
}
}
SERVER_END_REQ
;
switch
(
type
)
{
case
APC_NONE
:
return
;
/* no more APCs */
case
APC_ASYNC
:
proc
(
args
[
0
],
args
[
1
]);
break
;
case
APC_USER
:
proc
(
args
[
0
]
);
break
;
case
APC_TIMER
:
/* convert sec/usec to NT time */
DOSFS_UnixTimeToFileTime
(
(
time_t
)
args
[
0
],
&
ft
,
(
DWORD
)
args
[
1
]
*
10
);
proc
(
args
[
2
],
ft
.
dwLowDateTime
,
ft
.
dwHighDateTime
);
break
;
case
APC_ASYNC_IO
:
check_async_list
(
args
[
0
],
(
DWORD
)
args
[
1
]);
break
;
default:
server_protocol_error
(
"get_apc_request: bad type %d
\n
"
,
type
);
break
;
}
}
}
/***********************************************************************
* Sleep (KERNEL32.@)
*/
VOID
WINAPI
Sleep
(
DWORD
timeout
)
...
...
@@ -233,46 +79,27 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
BOOL
wait_all
,
DWORD
timeout
,
BOOL
alertable
)
{
int
ret
,
cookie
;
struct
timeval
tv
;
NTSTATUS
status
;
if
(
count
>
MAXIMUM_WAIT_OBJECTS
)
if
(
timeout
==
INFINITE
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
WAIT_FAILED
;
status
=
NtWaitForMultipleObjects
(
count
,
handles
,
wait_all
,
alertable
,
NULL
);
}
if
(
timeout
==
INFINITE
)
tv
.
tv_sec
=
tv
.
tv_usec
=
0
;
else
get_timeout
(
&
tv
,
timeout
);
for
(;;)
else
{
SERVER_START_REQ
(
select
)
{
req
->
flags
=
SELECT_INTERRUPTIBLE
;
req
->
cookie
=
&
cookie
;
req
->
sec
=
tv
.
tv_sec
;
req
->
usec
=
tv
.
tv_usec
;
wine_server_add_data
(
req
,
handles
,
count
*
sizeof
(
HANDLE
)
);
if
(
wait_all
)
req
->
flags
|=
SELECT_ALL
;
if
(
alertable
)
req
->
flags
|=
SELECT_ALERTABLE
;
if
(
timeout
!=
INFINITE
)
req
->
flags
|=
SELECT_TIMEOUT
;
LARGE_INTEGER
time
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
==
STATUS_PENDING
)
ret
=
wait_reply
(
&
cookie
);
if
(
ret
!=
STATUS_USER_APC
)
break
;
call_apcs
(
alertable
);
if
(
alertable
)
break
;
time
.
QuadPart
=
timeout
*
(
ULONGLONG
)
10000
;
time
.
QuadPart
=
-
time
.
QuadPart
;
status
=
NtWaitForMultipleObjects
(
count
,
handles
,
wait_all
,
alertable
,
&
time
);
}
if
(
HIWORD
(
ret
))
/* is it an error code? */
if
(
HIWORD
(
status
))
/* is it an error code? */
{
SetLastError
(
RtlNtStatusToDosError
(
ret
)
);
ret
=
WAIT_FAILED
;
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
status
=
WAIT_FAILED
;
}
return
ret
;
return
status
;
}
...
...
scheduler/timer.c
View file @
fbef57c0
...
...
@@ -29,9 +29,9 @@
#include "winerror.h"
#include "winnls.h"
#include "wine/unicode.h"
#include "file.h"
/* for FILETIME routines */
#include "wine/server.h"
#include "wine/debug.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
timer
);
...
...
@@ -130,34 +130,21 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per
PTIMERAPCROUTINE
callback
,
LPVOID
arg
,
BOOL
resume
)
{
BOOL
ret
;
LARGE_INTEGER
exp
=
*
when
;
struct
timeval
tv
;
if
(
exp
.
s
.
HighPart
<
0
)
/* relative time */
if
(
!
when
->
s
.
LowPart
&&
!
when
->
s
.
HighPart
)
{
LARGE_INTEGER
now
;
NtQuerySystemTime
(
&
now
)
;
exp
.
QuadPart
=
RtlLargeIntegerSubtract
(
now
.
QuadPart
,
exp
.
QuadPart
)
;
/* special case to start timeout on now+period without too many calculations */
tv
.
tv_sec
=
0
;
tv
.
tv_usec
=
0
;
}
else
NTDLL_get_server_timeout
(
&
tv
,
when
);
SERVER_START_REQ
(
set_timer
)
{
if
(
!
exp
.
s
.
LowPart
&&
!
exp
.
s
.
HighPart
)
{
/* special case to start timeout on now+period without too many calculations */
req
->
sec
=
0
;
req
->
usec
=
0
;
}
else
{
DWORD
remainder
;
FILETIME
ft
;
ft
.
dwLowDateTime
=
exp
.
s
.
LowPart
;
ft
.
dwHighDateTime
=
exp
.
s
.
HighPart
;
req
->
sec
=
DOSFS_FileTimeToUnixTime
(
&
ft
,
&
remainder
);
req
->
usec
=
remainder
/
10
;
/* convert from 100-ns to us units */
}
req
->
handle
=
handle
;
req
->
sec
=
tv
.
tv_sec
;
req
->
usec
=
tv
.
tv_usec
;
req
->
period
=
period
;
req
->
callback
=
callback
;
req
->
arg
=
arg
;
...
...
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