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
000c9800
Commit
000c9800
authored
Dec 13, 1999
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use waitable timers to implement service thread timers.
parent
247b8aee
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
48 additions
and
125 deletions
+48
-125
services.c
scheduler/services.c
+34
-122
timer.c
scheduler/timer.c
+14
-3
No files found.
scheduler/services.c
View file @
000c9800
...
...
@@ -13,10 +13,6 @@
DEFAULT_DEBUG_CHANNEL
(
timer
)
#define SERVICE_USE_OBJECT 0x0001
#define SERVICE_USE_TIMEOUT 0x0002
#define SERVICE_DISABLED 0x8000
typedef
struct
_SERVICE
{
struct
_SERVICE
*
next
;
...
...
@@ -25,13 +21,8 @@ typedef struct _SERVICE
PAPCFUNC
callback
;
ULONG_PTR
callback_arg
;
int
flags
;
BOOL
disabled
;
HANDLE
object
;
long
rate
;
struct
timeval
expire
;
}
SERVICE
;
typedef
struct
_SERVICETABLE
...
...
@@ -44,32 +35,12 @@ typedef struct _SERVICETABLE
}
SERVICETABLE
;
/***********************************************************************
* SERVICE_AddTimeval
*/
static
void
SERVICE_AddTimeval
(
struct
timeval
*
time
,
long
delta
)
{
delta
+=
time
->
tv_usec
;
time
->
tv_sec
+=
delta
/
1000000L
;
time
->
tv_usec
=
delta
%
1000000L
;
}
/***********************************************************************
* SERVICE_DiffTimeval
*/
static
long
SERVICE_DiffTimeval
(
struct
timeval
*
time1
,
struct
timeval
*
time2
)
{
return
(
time1
->
tv_sec
-
time2
->
tv_sec
)
*
1000000L
+
(
time1
->
tv_usec
-
time2
->
tv_usec
);
}
/***********************************************************************
* SERVICE_Loop
*/
static
DWORD
CALLBACK
SERVICE_Loop
(
SERVICETABLE
*
service
)
{
HANDLE
handles
[
MAXIMUM_WAIT_OBJECTS
];
int
count
=
0
;
DWORD
timeout
=
INFINITE
;
DWORD
retval
=
WAIT_FAILED
;
while
(
TRUE
)
...
...
@@ -80,44 +51,24 @@ static DWORD CALLBACK SERVICE_Loop( SERVICETABLE *service )
/* Check whether some condition is fulfilled */
struct
timeval
curTime
;
gettimeofday
(
&
curTime
,
NULL
);
HeapLock
(
GetProcessHeap
()
);
callback
=
NULL
;
callback_arg
=
0L
;
for
(
s
=
service
->
first
;
s
;
s
=
s
->
next
)
{
if
(
s
->
flags
&
SERVICE_DISABLED
)
continue
;
if
(
s
->
flags
&
SERVICE_USE_OBJECT
)
{
if
(
retval
>=
WAIT_OBJECT_0
&&
retval
<
WAIT_OBJECT_0
+
count
)
{
if
(
handles
[
retval
-
WAIT_OBJECT_0
]
==
s
->
object
)
{
retval
=
WAIT_TIMEOUT
;
callback
=
s
->
callback
;
callback_arg
=
s
->
callback_arg
;
break
;
}
}
}
if
(
s
->
flags
&
SERVICE_USE_TIMEOUT
)
if
(
s
->
disabled
)
continue
;
if
(
retval
>=
WAIT_OBJECT_0
&&
retval
<
WAIT_OBJECT_0
+
count
)
{
if
((
s
->
expire
.
tv_sec
<
curTime
.
tv_sec
)
||
((
s
->
expire
.
tv_sec
==
curTime
.
tv_sec
)
&&
(
s
->
expire
.
tv_usec
<=
curTime
.
tv_usec
)))
if
(
handles
[
retval
-
WAIT_OBJECT_0
]
==
s
->
object
)
{
SERVICE_AddTimeval
(
&
s
->
expire
,
s
->
rate
)
;
retval
=
WAIT_TIMEOUT
;
callback
=
s
->
callback
;
callback_arg
=
s
->
callback_arg
;
break
;
}
}
}
}
HeapUnlock
(
GetProcessHeap
()
);
...
...
@@ -135,23 +86,12 @@ static DWORD CALLBACK SERVICE_Loop( SERVICETABLE *service )
HeapLock
(
GetProcessHeap
()
);
count
=
0
;
timeout
=
INFINITE
;
for
(
s
=
service
->
first
;
s
;
s
=
s
->
next
)
{
if
(
s
->
flags
&
SERVICE_DISABLED
)
continue
;
if
(
s
->
flags
&
SERVICE_USE_OBJECT
)
if
(
count
<
MAXIMUM_WAIT_OBJECTS
)
handles
[
count
++
]
=
s
->
object
;
if
(
s
->
disabled
)
continue
;
if
(
s
->
flags
&
SERVICE_USE_TIMEOUT
)
{
long
delta
=
SERVICE_DiffTimeval
(
&
s
->
expire
,
&
curTime
);
long
time
=
(
delta
+
999L
)
/
1000L
;
if
(
time
<
1
)
time
=
1
;
if
(
time
<
timeout
)
timeout
=
time
;
}
if
(
count
<
MAXIMUM_WAIT_OBJECTS
)
handles
[
count
++
]
=
s
->
object
;
}
HeapUnlock
(
GetProcessHeap
()
);
...
...
@@ -159,11 +99,9 @@ static DWORD CALLBACK SERVICE_Loop( SERVICETABLE *service )
/* Wait until some condition satisfied */
TRACE
(
"Waiting for %d objects with timeout %ld
\n
"
,
count
,
timeout
);
TRACE
(
"Waiting for %d objects
\n
"
,
count
);
retval
=
WaitForMultipleObjectsEx
(
count
,
handles
,
FALSE
,
timeout
,
TRUE
);
retval
=
WaitForMultipleObjectsEx
(
count
,
handles
,
FALSE
,
INFINITE
,
TRUE
);
TRACE
(
"Wait returned: %ld
\n
"
,
retval
);
}
...
...
@@ -233,7 +171,7 @@ HANDLE SERVICE_AddObject( HANDLE object,
s
->
callback
=
callback
;
s
->
callback_arg
=
callback_arg
;
s
->
object
=
object
;
s
->
flags
=
SERVICE_USE_OBJECT
;
s
->
disabled
=
FALSE
;
HeapLock
(
GetProcessHeap
()
);
...
...
@@ -254,39 +192,30 @@ HANDLE SERVICE_AddObject( HANDLE object,
HANDLE
SERVICE_AddTimer
(
LONG
rate
,
PAPCFUNC
callback
,
ULONG_PTR
callback_arg
)
{
SERVICE
*
s
;
SERVICETABLE
*
service_table
;
HANDLE
handle
;
HANDLE
handle
,
ret
;
LARGE_INTEGER
when
;
if
(
!
rate
||
!
callback
)
return
INVALID_HANDLE_VALUE
;
if
(
PROCESS_Current
()
->
service_table
==
0
&&
!
SERVICE_CreateServiceTable
())
return
INVALID_HANDLE_VALUE
;
service_table
=
PROCESS_Current
()
->
service_table
;
s
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
SERVICE
)
);
if
(
!
s
)
return
INVALID_HANDLE_VALUE
;
s
->
callback
=
callback
;
s
->
callback_arg
=
callback_arg
;
s
->
rate
=
rate
;
s
->
flags
=
SERVICE_USE_TIMEOUT
;
gettimeofday
(
&
s
->
expire
,
NULL
);
SERVICE_AddTimeval
(
&
s
->
expire
,
s
->
rate
);
HeapLock
(
GetProcessHeap
()
);
s
->
self
=
handle
=
(
HANDLE
)
++
service_table
->
counter
;
s
->
next
=
service_table
->
first
;
service_table
->
first
=
s
;
handle
=
CreateWaitableTimerA
(
NULL
,
FALSE
,
NULL
);
if
(
!
handle
)
return
INVALID_HANDLE_VALUE
;
HeapUnlock
(
GetProcessHeap
()
);
QueueUserAPC
(
NULL
,
service_table
->
thread
,
0L
);
rate
=
(
rate
+
500
)
/
1000
;
/* us -> ms */
if
(
!
rate
)
rate
=
1
;
when
.
s
.
LowPart
=
when
.
s
.
HighPart
=
0
;
if
(
!
SetWaitableTimer
(
handle
,
&
when
,
rate
,
NULL
,
NULL
,
FALSE
))
{
CloseHandle
(
handle
);
return
INVALID_HANDLE_VALUE
;
}
return
handle
;
if
((
ret
=
SERVICE_AddObject
(
handle
,
callback
,
callback_arg
))
==
INVALID_HANDLE_VALUE
)
{
CloseHandle
(
handle
);
return
INVALID_HANDLE_VALUE
;
}
return
ret
;
}
/***********************************************************************
...
...
@@ -309,9 +238,7 @@ BOOL SERVICE_Delete( HANDLE service )
{
if
(
(
*
s
)
->
self
==
service
)
{
if
(
(
*
s
)
->
flags
&
SERVICE_USE_OBJECT
)
handle
=
(
*
s
)
->
object
;
handle
=
(
*
s
)
->
object
;
next
=
(
*
s
)
->
next
;
HeapFree
(
GetProcessHeap
(),
0
,
*
s
);
*
s
=
next
;
...
...
@@ -349,22 +276,7 @@ BOOL SERVICE_Enable( HANDLE service )
{
if
(
s
->
self
==
service
)
{
if
(
s
->
flags
&
SERVICE_DISABLED
)
{
s
->
flags
&=
~
SERVICE_DISABLED
;
if
(
s
->
flags
&
SERVICE_USE_TIMEOUT
)
{
long
delta
;
struct
timeval
curTime
;
gettimeofday
(
&
curTime
,
NULL
);
delta
=
SERVICE_DiffTimeval
(
&
s
->
expire
,
&
curTime
);
if
(
delta
>
0
)
SERVICE_AddTimeval
(
&
s
->
expire
,
(
delta
/
s
->
rate
)
*
s
->
rate
);
}
}
s
->
disabled
=
FALSE
;
retv
=
TRUE
;
break
;
}
...
...
@@ -396,7 +308,7 @@ BOOL SERVICE_Disable( HANDLE service )
{
if
(
s
->
self
==
service
)
{
s
->
flags
|=
SERVICE_DISABLED
;
s
->
disabled
=
TRUE
;
retv
=
TRUE
;
break
;
}
...
...
scheduler/timer.c
View file @
000c9800
...
...
@@ -89,8 +89,9 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per
if
(
when
->
s
.
HighPart
<
0
)
/* relative time */
{
DWORD
low
=
ft
.
dwLowDateTime
;
DWORD
low
;
GetSystemTimeAsFileTime
(
&
ft
);
low
=
ft
.
dwLowDateTime
;
ft
.
dwLowDateTime
-=
when
->
s
.
LowPart
;
ft
.
dwHighDateTime
-=
when
->
s
.
HighPart
;
if
(
low
<
ft
.
dwLowDateTime
)
ft
.
dwHighDateTime
--
;
/* overflow */
...
...
@@ -100,9 +101,19 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per
ft
.
dwLowDateTime
=
when
->
s
.
LowPart
;
ft
.
dwHighDateTime
=
when
->
s
.
HighPart
;
}
if
(
!
ft
.
dwLowDateTime
&&
!
ft
.
dwHighDateTime
)
{
/* special case to start timeout on now+period without too many calculations */
req
->
sec
=
0
;
req
->
usec
=
0
;
}
else
{
req
->
sec
=
DOSFS_FileTimeToUnixTime
(
&
ft
,
&
remainder
);
req
->
usec
=
remainder
/
10
;
/* convert from 100-ns to us units */
}
req
->
handle
=
handle
;
req
->
sec
=
DOSFS_FileTimeToUnixTime
(
&
ft
,
&
remainder
);
req
->
usec
=
remainder
/
10
;
/* convert from 100-ns to us units */
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