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
7761cbe0
Commit
7761cbe0
authored
Apr 11, 1999
by
Ulrich Weigand
Committed by
Alexandre Julliard
Apr 11, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented 'kernel services thread'.
parent
f66bf566
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
399 additions
and
0 deletions
+399
-0
services.h
include/services.h
+28
-0
main.c
loader/main.c
+4
-0
Makefile.in
scheduler/Makefile.in
+1
-0
services.c
scheduler/services.c
+366
-0
No files found.
include/services.h
0 → 100644
View file @
7761cbe0
/*
* Kernel Service Thread API
*
* Copyright 1999 Ulrich Weigand
*/
#ifndef __WINE_SERVICES_H
#define __WINE_SERVICES_H
#include "winbase.h"
BOOL
SERVICE_Init
(
void
);
HANDLE
SERVICE_AddObject
(
HANDLE
object
,
PAPCFUNC
callback
,
ULONG_PTR
callback_arg
);
HANDLE
SERVICE_AddTimer
(
LONG
rate
,
PAPCFUNC
callback
,
ULONG_PTR
callback_arg
);
BOOL
SERVICE_Delete
(
HANDLE
service
);
BOOL
SERVICE_Enable
(
HANDLE
service
);
BOOL
SERVICE_Disable
(
HANDLE
service
);
#endif
/* __WINE_SERVICES_H */
loader/main.c
View file @
7761cbe0
...
...
@@ -39,6 +39,7 @@
#include "shell.h"
#include "winproc.h"
#include "syslevel.h"
#include "services.h"
#include "thread.h"
#include "task.h"
#include "debug.h"
...
...
@@ -62,6 +63,9 @@ BOOL MAIN_MainInit(void)
/* Initialize signal handling */
if
(
!
SIGNAL_Init
())
return
FALSE
;
/* Initialize kernel services thread */
if
(
!
SERVICE_Init
())
return
FALSE
;
/* Load the configuration file */
if
(
!
PROFILE_LoadWineIni
())
return
FALSE
;
...
...
scheduler/Makefile.in
View file @
7761cbe0
...
...
@@ -14,6 +14,7 @@ C_SRCS = \
pipe.c
\
process.c
\
semaphore.c
\
services.c
\
synchro.c
\
sysdeps.c
\
syslevel.c
\
...
...
scheduler/services.c
0 → 100644
View file @
7761cbe0
/*
* Kernel Services Thread
*
* Copyright 1999 Ulrich Weigand
*/
#include <sys/time.h>
#include <unistd.h>
#include "services.h"
#include "debug.h"
#define SERVICE_USE_OBJECT 0x0001
#define SERVICE_USE_TIMEOUT 0x0002
#define SERVICE_DISABLED 0x8000
typedef
struct
_SERVICE
{
struct
_SERVICE
*
next
;
HANDLE
self
;
PAPCFUNC
callback
;
ULONG_PTR
callback_arg
;
int
flags
;
HANDLE
object
;
long
rate
;
struct
timeval
expire
;
}
SERVICE
;
typedef
struct
{
HANDLE
heap
;
HANDLE
thread
;
SERVICE
*
first
;
DWORD
counter
;
}
SERVICETABLE
;
static
SERVICETABLE
*
Service
=
NULL
;
/***********************************************************************
* 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
)
{
PAPCFUNC
callback
;
ULONG_PTR
callback_arg
;
SERVICE
*
s
;
/* Check whether some condition is fulfilled */
struct
timeval
curTime
;
gettimeofday
(
&
curTime
,
NULL
);
HeapLock
(
service
->
heap
);
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
)
{
callback
=
s
->
callback
;
callback_arg
=
s
->
callback_arg
;
break
;
}
if
(
s
->
flags
&
SERVICE_USE_TIMEOUT
)
if
(
timercmp
(
&
s
->
expire
,
&
curTime
,
<
)
)
{
SERVICE_AddTimeval
(
&
s
->
expire
,
s
->
rate
);
callback
=
s
->
callback
;
callback_arg
=
s
->
callback_arg
;
break
;
}
}
HeapUnlock
(
service
->
heap
);
/* If found, call callback routine */
if
(
callback
)
{
callback
(
callback_arg
);
continue
;
}
/* If not found, determine wait condition */
HeapLock
(
service
->
heap
);
count
=
0
;
timeout
=
INFINITE
;
for
(
s
=
service
->
first
;
s
;
s
=
s
->
next
)
{
if
(
s
->
flags
&
SERVICE_DISABLED
)
continue
;
if
(
s
->
flags
&
SERVICE_USE_OBJECT
)
handles
[
count
++
]
=
s
->
object
;
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
;
}
}
HeapUnlock
(
service
->
heap
);
/* Wait until some condition satisfied */
TRACE
(
timer
,
"Waiting for %d objects with timeout %ld
\n
"
,
count
,
timeout
);
retval
=
WaitForMultipleObjectsEx
(
count
,
handles
,
FALSE
,
timeout
,
TRUE
);
TRACE
(
timer
,
"Wait returned: %ld
\n
"
,
retval
);
}
return
0L
;
}
/***********************************************************************
* SERVICE_Init
*/
BOOL
SERVICE_Init
(
void
)
{
HANDLE
heap
,
thread
;
heap
=
HeapCreate
(
HEAP_GROWABLE
,
0x1000
,
0
);
if
(
!
heap
)
return
FALSE
;
Service
=
HeapAlloc
(
heap
,
HEAP_ZERO_MEMORY
,
sizeof
(
SERVICETABLE
)
);
if
(
!
Service
)
{
HeapDestroy
(
heap
);
return
FALSE
;
}
Service
->
heap
=
heap
;
thread
=
CreateThread
(
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
SERVICE_Loop
,
Service
,
0
,
NULL
);
if
(
thread
==
INVALID_HANDLE_VALUE
)
{
HeapDestroy
(
heap
);
return
FALSE
;
}
Service
->
thread
=
ConvertToGlobalHandle
(
thread
);
return
TRUE
;
}
/***********************************************************************
* SERVICE_AddObject
*/
HANDLE
SERVICE_AddObject
(
HANDLE
object
,
PAPCFUNC
callback
,
ULONG_PTR
callback_arg
)
{
SERVICE
*
s
;
HANDLE
handle
;
if
(
!
Service
||
object
==
INVALID_HANDLE_VALUE
||
!
callback
)
return
INVALID_HANDLE_VALUE
;
s
=
HeapAlloc
(
Service
->
heap
,
HEAP_ZERO_MEMORY
,
sizeof
(
SERVICE
)
);
if
(
!
s
)
return
INVALID_HANDLE_VALUE
;
HeapLock
(
Service
->
heap
);
s
->
callback
=
callback
;
s
->
callback_arg
=
callback_arg
;
s
->
object
=
object
;
s
->
flags
=
SERVICE_USE_OBJECT
;
s
->
self
=
handle
=
(
HANDLE
)
++
Service
->
counter
;
s
->
next
=
Service
->
first
;
Service
->
first
=
s
;
HeapUnlock
(
Service
->
heap
);
QueueUserAPC
(
NULL
,
Service
->
thread
,
0L
);
return
handle
;
}
/***********************************************************************
* SERVICE_AddTimer
*/
HANDLE
SERVICE_AddTimer
(
LONG
rate
,
PAPCFUNC
callback
,
ULONG_PTR
callback_arg
)
{
SERVICE
*
s
;
HANDLE
handle
;
if
(
!
Service
||
!
rate
||
!
callback
)
return
INVALID_HANDLE_VALUE
;
s
=
HeapAlloc
(
Service
->
heap
,
HEAP_ZERO_MEMORY
,
sizeof
(
SERVICE
)
);
if
(
!
s
)
return
INVALID_HANDLE_VALUE
;
HeapLock
(
Service
->
heap
);
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
);
s
->
self
=
handle
=
(
HANDLE
)
++
Service
->
counter
;
s
->
next
=
Service
->
first
;
Service
->
first
=
s
;
HeapUnlock
(
Service
->
heap
);
QueueUserAPC
(
NULL
,
Service
->
thread
,
0L
);
return
handle
;
}
/***********************************************************************
* SERVICE_Delete
*/
BOOL
SERVICE_Delete
(
HANDLE
service
)
{
BOOL
retv
=
TRUE
;
SERVICE
**
s
;
if
(
!
Service
)
return
retv
;
HeapLock
(
Service
->
heap
);
for
(
s
=
&
Service
->
first
;
*
s
;
s
=
&
(
*
s
)
->
next
)
if
(
(
*
s
)
->
self
==
service
)
{
*
s
=
(
*
s
)
->
next
;
HeapFree
(
Service
->
heap
,
0
,
*
s
);
retv
=
FALSE
;
break
;
}
HeapUnlock
(
Service
->
heap
);
QueueUserAPC
(
NULL
,
Service
->
thread
,
0L
);
return
retv
;
}
/***********************************************************************
* SERVICE_Enable
*/
BOOL
SERVICE_Enable
(
HANDLE
service
)
{
BOOL
retv
=
TRUE
;
SERVICE
*
s
;
if
(
!
Service
)
return
retv
;
HeapLock
(
Service
->
heap
);
for
(
s
=
Service
->
first
;
s
;
s
=
s
->
next
)
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
);
}
}
retv
=
FALSE
;
break
;
}
HeapUnlock
(
Service
->
heap
);
QueueUserAPC
(
NULL
,
Service
->
thread
,
0L
);
return
retv
;
}
/***********************************************************************
* SERVICE_Disable
*/
BOOL
SERVICE_Disable
(
HANDLE
service
)
{
BOOL
retv
=
TRUE
;
SERVICE
*
s
;
if
(
!
Service
)
return
retv
;
HeapLock
(
Service
->
heap
);
for
(
s
=
Service
->
first
;
s
;
s
=
s
->
next
)
if
(
s
->
self
==
service
)
{
s
->
flags
|=
SERVICE_DISABLED
;
retv
=
FALSE
;
break
;
}
HeapUnlock
(
Service
->
heap
);
QueueUserAPC
(
NULL
,
Service
->
thread
,
0L
);
return
retv
;
}
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