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
55443878
Commit
55443878
authored
Dec 31, 1998
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed client-side wait functions; all waiting is now done through
the server.
parent
63cb0f8b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
301 additions
and
1369 deletions
+301
-1369
change.c
files/change.c
+19
-62
file.c
files/file.c
+30
-109
k32obj.h
include/k32obj.h
+0
-6
process.h
include/process.h
+4
-2
thread.h
include/thread.h
+1
-14
signal.c
loader/signal.c
+0
-4
virtual.c
memory/virtual.c
+0
-7
toolhelp.c
misc/toolhelp.c
+0
-6
client.c
scheduler/client.c
+0
-26
event.c
scheduler/event.c
+42
-182
handle.c
scheduler/handle.c
+56
-0
k32obj.c
scheduler/k32obj.c
+1
-8
mutex.c
scheduler/mutex.c
+29
-171
pipe.c
scheduler/pipe.c
+0
-6
process.c
scheduler/process.c
+34
-119
semaphore.c
scheduler/semaphore.c
+35
-123
synchro.c
scheduler/synchro.c
+9
-257
thread.c
scheduler/thread.c
+12
-91
console.c
win32/console.c
+25
-170
device.c
win32/device.c
+1
-6
queue.c
windows/queue.c
+3
-0
No files found.
files/change.c
View file @
55443878
...
...
@@ -15,22 +15,13 @@
#include "process.h"
#include "thread.h"
#include "heap.h"
#include "server.h"
#include "debug.h"
static
BOOL32
CHANGE_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
CHANGE_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
CHANGE_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
CHANGE_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
CHANGE_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
CHANGE_Ops
=
{
CHANGE_Signaled
,
/* signaled */
CHANGE_Satisfied
,
/* satisfied */
CHANGE_AddWait
,
/* add_wait */
CHANGE_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
CHANGE_Destroy
/* destroy */
};
...
...
@@ -48,51 +39,6 @@ typedef struct
}
CHANGE_OBJECT
;
/***********************************************************************
* CHANGE_Signaled
*/
static
BOOL32
CHANGE_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
CHANGE_OBJECT
*
change
=
(
CHANGE_OBJECT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_CHANGE
);
return
change
->
notify
;
}
/***********************************************************************
* CHANGE_Satisfied
*
* Wait on this object has been satisfied.
*/
static
BOOL32
CHANGE_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
assert
(
obj
->
type
==
K32OBJ_CHANGE
);
return
FALSE
;
/* Not abandoned */
}
/***********************************************************************
* CHANGE_AddWait
*
* Add thread to object wait queue.
*/
static
void
CHANGE_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
CHANGE_OBJECT
*
change
=
(
CHANGE_OBJECT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_CHANGE
);
THREAD_AddQueue
(
&
change
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/***********************************************************************
* CHANGE_RemoveWait
*
* Remove thread from object wait queue.
*/
static
void
CHANGE_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
CHANGE_OBJECT
*
change
=
(
CHANGE_OBJECT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_CHANGE
);
THREAD_RemoveQueue
(
&
change
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/****************************************************************************
* CHANGE_Destroy
*/
...
...
@@ -118,11 +64,24 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
BOOL32
bWatchSubtree
,
DWORD
dwNotifyFilter
)
{
HANDLE32
handle
;
CHANGE_OBJECT
*
change
;
struct
create_change_notification_request
req
;
struct
create_change_notification_reply
reply
;
int
len
;
req
.
subtree
=
bWatchSubtree
;
req
.
filter
=
dwNotifyFilter
;
CLIENT_SendRequest
(
REQ_CREATE_CHANGE_NOTIFICATION
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
==
-
1
)
return
INVALID_HANDLE_VALUE32
;
change
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
CHANGE_OBJECT
)
);
if
(
!
change
)
return
INVALID_HANDLE_VALUE32
;
if
(
!
change
)
{
CLIENT_CloseHandle
(
reply
.
handle
);
return
INVALID_HANDLE_VALUE32
;
}
change
->
header
.
type
=
K32OBJ_CHANGE
;
change
->
header
.
refcount
=
1
;
...
...
@@ -134,11 +93,9 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
change
->
wait_queue
=
NULL
;
change
->
notify
=
FALSE
;
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
&
change
->
header
,
FILE_ALL_ACCESS
/*FIXME*/
,
TRUE
,
-
1
);
/* If the allocation failed, the object is already destroyed */
if
(
handle
==
INVALID_HANDLE_VALUE32
)
change
=
NULL
;
return
handle
;
return
HANDLE_Alloc
(
PROCESS_Current
(),
&
change
->
header
,
STANDARD_RIGHTS_REQUIRED
|
SYNCHRONIZE
/*FIXME*/
,
FALSE
,
reply
.
handle
);
}
/****************************************************************************
...
...
files/file.c
View file @
55443878
...
...
@@ -45,29 +45,10 @@
#define MAP_ANON MAP_ANONYMOUS
#endif
#if 0
static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD tid);
static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id);
static void FILE_AddWait(K32OBJ *ptr, DWORD tid);
static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id);
#endif
static
void
FILE_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
FILE_Ops
=
{
#if 0
FILE_Signaled, /* signaled */
FILE_Satisfied, /* satisfied */
FILE_AddWait, /* add_wait */
FILE_RemoveWait, /* remove_wait */
#else
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
#endif
NULL
,
/* read */
NULL
,
/* write */
FILE_Destroy
/* destroy */
};
...
...
@@ -126,58 +107,6 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle )
return
handle
;
}
/***********************************************************************
* FILE_async_handler [internal]
*/
#if 0
static void
FILE_async_handler(int unixfd,void *private) {
FILE_OBJECT *file = (FILE_OBJECT*)private;
SYNC_WakeUp(&file->wait_queue,INFINITE32);
}
static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD thread_id)
{
fd_set fds,*readfds = NULL,*writefds = NULL;
struct timeval tv;
FILE_OBJECT *file = (FILE_OBJECT *)ptr;
FD_ZERO(&fds);
FD_SET(file->unix_handle,&fds);
if (file->mode == OF_READ) readfds = &fds;
if (file->mode == OF_WRITE) writefds = &fds;
if (file->mode == OF_READWRITE) {writefds = &fds; readfds = &fds;}
tv.tv_sec = 0;
tv.tv_usec = 0;
assert(readfds || writefds);
if (select(file->unix_handle+1,readfds,writefds,NULL,&tv)>0)
return TRUE; /* we triggered one fd. Whereever. */
return FALSE;
}
static void FILE_AddWait(K32OBJ *ptr, DWORD thread_id)
{
FILE_OBJECT *file = (FILE_OBJECT*)ptr;
if (!file->wait_queue)
ASYNC_RegisterFD(file->unix_handle,FILE_async_handler,file);
THREAD_AddQueue(&file->wait_queue,thread_id);
}
static void FILE_RemoveWait(K32OBJ *ptr, DWORD thread_id)
{
FILE_OBJECT *file = (FILE_OBJECT*)ptr;
THREAD_RemoveQueue(&file->wait_queue,thread_id);
if (!file->wait_queue)
ASYNC_UnregisterFD(file->unix_handle,FILE_async_handler);
}
static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id)
{
return FALSE; /* not abandoned. Hmm? */
}
#endif
/***********************************************************************
* FILE_Destroy
...
...
@@ -1248,6 +1177,7 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
{
K32OBJ
*
ptr
;
struct
get_read_fd_request
req
;
int
unix_handle
,
result
;
TRACE
(
file
,
"%d %p %ld
\n
"
,
hFile
,
buffer
,
bytesToRead
);
...
...
@@ -1258,29 +1188,25 @@ BOOL32 WINAPI ReadFile( HANDLE32 hFile, LPVOID buffer, DWORD bytesToRead,
K32OBJ_UNKNOWN
,
GENERIC_READ
,
&
req
.
handle
)))
return
FALSE
;
if
(
req
.
handle
!=
-
1
)
/* We have
a server handle */
if
(
req
.
handle
==
-
1
)
/* We need
a server handle */
{
int
unix_handle
,
result
;
CLIENT_SendRequest
(
REQ_GET_READ_FD
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitReply
(
NULL
,
&
unix_handle
,
0
);
if
(
unix_handle
==
-
1
)
return
FALSE
;
if
((
result
=
read
(
unix_handle
,
buffer
,
bytesToRead
))
==
-
1
)
FILE_SetDosError
();
close
(
unix_handle
);
K32OBJ_DecCount
(
ptr
);
if
(
result
==
-
1
)
return
FALSE
;
if
(
bytesRead
)
*
bytesRead
=
result
;
return
TRUE
;
return
FALSE
;
}
else
CLIENT_SendRequest
(
REQ_GET_READ_FD
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitReply
(
NULL
,
&
unix_handle
,
0
);
K32OBJ_DecCount
(
ptr
);
if
(
unix_handle
==
-
1
)
return
FALSE
;
while
((
result
=
read
(
unix_handle
,
buffer
,
bytesToRead
))
==
-
1
)
{
BOOL32
status
=
FALSE
;
if
(
K32OBJ_OPS
(
ptr
)
->
read
)
status
=
K32OBJ_OPS
(
ptr
)
->
read
(
ptr
,
buffer
,
bytesToRead
,
bytesRead
,
overlapped
);
K32OBJ_DecCount
(
ptr
);
return
status
;
if
((
errno
==
EAGAIN
)
||
(
errno
==
EINTR
))
continue
;
FILE_SetDosError
();
break
;
}
close
(
unix_handle
);
if
(
result
==
-
1
)
return
FALSE
;
if
(
bytesRead
)
*
bytesRead
=
result
;
return
TRUE
;
}
...
...
@@ -1292,6 +1218,7 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
{
K32OBJ
*
ptr
;
struct
get_write_fd_request
req
;
int
unix_handle
,
result
;
TRACE
(
file
,
"%d %p %ld
\n
"
,
hFile
,
buffer
,
bytesToWrite
);
...
...
@@ -1302,31 +1229,25 @@ BOOL32 WINAPI WriteFile( HANDLE32 hFile, LPCVOID buffer, DWORD bytesToWrite,
K32OBJ_UNKNOWN
,
GENERIC_WRITE
,
&
req
.
handle
)))
return
FALSE
;
if
(
req
.
handle
!=
-
1
)
/* We have
a server handle */
if
(
req
.
handle
==
-
1
)
/* We need
a server handle */
{
int
unix_handle
,
result
;
CLIENT_SendRequest
(
REQ_GET_WRITE_FD
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitReply
(
NULL
,
&
unix_handle
,
0
);
if
(
unix_handle
==
-
1
)
return
FALSE
;
if
((
result
=
write
(
unix_handle
,
buffer
,
bytesToWrite
))
==
-
1
)
FILE_SetDosError
();
close
(
unix_handle
);
K32OBJ_DecCount
(
ptr
);
if
(
result
==
-
1
)
return
FALSE
;
if
(
bytesWritten
)
*
bytesWritten
=
result
;
return
TRUE
;
return
FALSE
;
}
else
CLIENT_SendRequest
(
REQ_GET_WRITE_FD
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitReply
(
NULL
,
&
unix_handle
,
0
);
K32OBJ_DecCount
(
ptr
);
if
(
unix_handle
==
-
1
)
return
FALSE
;
while
((
result
=
write
(
unix_handle
,
buffer
,
bytesToWrite
))
==
-
1
)
{
BOOL32
status
=
FALSE
;
if
(
K32OBJ_OPS
(
ptr
)
->
write
)
status
=
K32OBJ_OPS
(
ptr
)
->
write
(
ptr
,
buffer
,
bytesToWrite
,
bytesWritten
,
overlapped
);
K32OBJ_DecCount
(
ptr
);
return
status
;
if
((
errno
==
EAGAIN
)
||
(
errno
==
EINTR
))
continue
;
FILE_SetDosError
();
break
;
}
close
(
unix_handle
);
if
(
result
==
-
1
)
return
FALSE
;
if
(
bytesWritten
)
*
bytesWritten
=
result
;
return
TRUE
;
}
...
...
include/k32obj.h
View file @
55443878
...
...
@@ -44,12 +44,6 @@ typedef struct
/* Kernel object operations */
typedef
struct
{
BOOL32
(
*
signaled
)(
K32OBJ
*
,
DWORD
);
/* Is object signaled? */
BOOL32
(
*
satisfied
)(
K32OBJ
*
,
DWORD
);
/* Wait on object is satisfied */
void
(
*
add_wait
)(
K32OBJ
*
,
DWORD
);
/* Add thread to wait queue */
void
(
*
remove_wait
)(
K32OBJ
*
,
DWORD
);
/* Remove thread from wait queue */
BOOL32
(
*
read
)(
K32OBJ
*
,
LPVOID
,
DWORD
,
LPDWORD
,
LPOVERLAPPED
);
BOOL32
(
*
write
)(
K32OBJ
*
,
LPCVOID
,
DWORD
,
LPDWORD
,
LPOVERLAPPED
);
void
(
*
destroy
)(
K32OBJ
*
);
/* Destroy object on refcount==0 */
}
K32OBJ_OPS
;
...
...
include/process.h
View file @
55443878
...
...
@@ -63,7 +63,7 @@ typedef struct _PDB32
{
K32OBJ
header
;
/* 00 Kernel object header */
DWORD
unknown1
;
/* 08 Unknown */
K32OBJ
*
event
;
/* 0c Pointer to an event object */
K32OBJ
*
event
;
/* 0c Pointer to an event object
(unused)
*/
DWORD
exit_code
;
/* 10 Process exit code */
DWORD
unknown2
;
/* 14 Unknown */
HANDLE32
heap
;
/* 18 Default process heap */
...
...
@@ -102,7 +102,7 @@ typedef struct _PDB32
K32OBJ
*
console_provider
;
/* b0 Console provider (??) */
WORD
env_selector
;
/* b4 Selector to process environment */
WORD
error_mode
;
/* b6 Error mode */
K32OBJ
*
load_done_evt
;
/* b8 Event for process loading done */
HANDLE32
load_done_evt
;
/* b8 Event for process loading done */
DWORD
unknown7
;
/* bc Unknown */
DWORD
unknown8
;
/* c0 Unknown (NT) */
LCID
locale
;
/* c4 Locale to be queried by GetThreadLocale (NT) */
...
...
@@ -136,6 +136,8 @@ extern HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access,
extern
K32OBJ
*
HANDLE_GetObjPtr
(
PDB32
*
pdb
,
HANDLE32
handle
,
K32OBJ_TYPE
type
,
DWORD
access
,
int
*
server_handle
);
extern
int
HANDLE_GetServerHandle
(
PDB32
*
pdb
,
HANDLE32
handle
,
K32OBJ_TYPE
type
,
DWORD
access
);
extern
BOOL32
HANDLE_SetObjPtr
(
PDB32
*
pdb
,
HANDLE32
handle
,
K32OBJ
*
ptr
,
DWORD
access
);
extern
void
HANDLE_CloseAll
(
PDB32
*
pdb
,
K32OBJ
*
ptr
);
...
...
include/thread.h
View file @
55443878
...
...
@@ -64,7 +64,6 @@ typedef struct
DWORD
signaled
;
/* Index of signaled object (or WAIT_FAILED)*/
BOOL32
wait_all
;
/* Wait for all objects flag */
BOOL32
wait_msg
;
/* Wait for message flag */
BOOL32
use_server
;
/* Use server call for waiting */
K32OBJ
*
objs
[
MAXIMUM_WAIT_OBJECTS
];
/* Object pointers */
int
server
[
MAXIMUM_WAIT_OBJECTS
];
/* Server handles */
}
WAIT_STRUCT
;
...
...
@@ -107,8 +106,7 @@ typedef struct _THDB
void
*
entry_point
;
/* 1c0 Thread entry point (was: unknown) */
void
*
entry_arg
;
/* 1c4 Entry point arg (was: unknown) */
int
unix_pid
;
/* 1c8 Unix thread pid (was: unknown) */
K32OBJ
*
mutex_list
;
/* 1cc List of owned mutex (was: unknown)*/
DWORD
unknown5
[
2
];
/* 1d0 Unknown */
DWORD
unknown5
[
3
];
/* 1cc Unknown */
DWORD
sys_count
[
4
];
/* 1d8 Syslevel mutex entry counters */
CRITICAL_SECTION
*
sys_mutex
[
4
];
/* 1e8 Syslevel mutex pointers */
DWORD
unknown6
[
2
];
/* 1f8 Unknown */
...
...
@@ -162,18 +160,7 @@ extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
extern
void
THREAD_RemoveQueue
(
THREAD_QUEUE
*
queue
,
THDB
*
thread
);
extern
DWORD
THREAD_TlsAlloc
(
THDB
*
thread
);
/* scheduler/event.c */
extern
void
EVENT_Set
(
K32OBJ
*
obj
);
extern
K32OBJ
*
EVENT_Create
(
BOOL32
manual_reset
,
BOOL32
initial_state
);
/* scheduler/mutex.c */
extern
void
MUTEX_Abandon
(
K32OBJ
*
obj
);
/* scheduler/synchro.c */
extern
void
SYNC_WaitForCondition
(
WAIT_STRUCT
*
wait
,
DWORD
timeout
);
extern
void
SYNC_WakeUp
(
THREAD_QUEUE
*
queue
,
DWORD
max
);
extern
void
SYNC_MsgWakeUp
(
THDB
*
thdb
);
extern
void
SYNC_SetupSignals
(
void
);
extern
DWORD
SYNC_DoWait
(
DWORD
count
,
const
HANDLE32
*
handles
,
BOOL32
wait_all
,
DWORD
timeout
,
BOOL32
alertable
,
BOOL32
wait_msg
);
...
...
loader/signal.c
View file @
55443878
...
...
@@ -156,8 +156,6 @@ extern void ASYNC_sigio(int a);
*/
BOOL32
SIGNAL_Init
(
void
)
{
extern
void
SYNC_SetupSignals
(
void
);
#ifdef HAVE_WORKING_SIGALTSTACK
struct
sigaltstack
ss
;
ss
.
ss_sp
=
SIGNAL_Stack
;
...
...
@@ -187,8 +185,6 @@ BOOL32 SIGNAL_Init(void)
/* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
signal
(
SIGPIPE
,
SIG_IGN
);
SYNC_SetupSignals
();
return
TRUE
;
}
...
...
memory/virtual.c
View file @
55443878
...
...
@@ -110,13 +110,6 @@ static void VIRTUAL_DestroyMapping( K32OBJ *obj );
const
K32OBJ_OPS
MEM_MAPPED_FILE_Ops
=
{
/* Object cannot be waited upon, so we don't need these (except destroy) */
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
VIRTUAL_DestroyMapping
/* destroy */
};
...
...
misc/toolhelp.c
View file @
55443878
...
...
@@ -29,12 +29,6 @@ static void SNAPSHOT_Destroy( K32OBJ *obj );
const
K32OBJ_OPS
SNAPSHOT_Ops
=
{
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
SNAPSHOT_Destroy
/* destroy */
};
...
...
scheduler/client.c
View file @
55443878
...
...
@@ -328,32 +328,6 @@ int CLIENT_SetDebug( int level )
}
/***********************************************************************
* CLIENT_TerminateProcess
*
* Send a terminate process request. Return 0 if OK.
*/
int
CLIENT_TerminateProcess
(
int
handle
,
int
exit_code
)
{
CLIENT_SendRequest
(
REQ_TERMINATE_PROCESS
,
-
1
,
2
,
&
handle
,
sizeof
(
handle
),
&
exit_code
,
sizeof
(
exit_code
)
);
return
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
/***********************************************************************
* CLIENT_TerminateThread
*
* Send a terminate thread request. Return 0 if OK.
*/
int
CLIENT_TerminateThread
(
int
handle
,
int
exit_code
)
{
CLIENT_SendRequest
(
REQ_TERMINATE_THREAD
,
-
1
,
2
,
&
handle
,
sizeof
(
handle
),
&
exit_code
,
sizeof
(
exit_code
)
);
return
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
/***********************************************************************
* CLIENT_CloseHandle
*
* Send a close handle request. Return 0 if OK.
...
...
scheduler/event.c
View file @
55443878
...
...
@@ -18,69 +18,17 @@
typedef
struct
{
K32OBJ
header
;
THREAD_QUEUE
wait_queue
;
BOOL32
manual_reset
;
BOOL32
signaled
;
}
EVENT
;
static
BOOL32
EVENT_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
EVENT_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
EVENT_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
EVENT_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
EVENT_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
EVENT_Ops
=
{
EVENT_Signaled
,
/* signaled */
EVENT_Satisfied
,
/* satisfied */
EVENT_AddWait
,
/* add_wait */
EVENT_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
EVENT_Destroy
/* destroy */
};
/***********************************************************************
* EVENT_Set
*
* Implementation of SetEvent. Used by ExitThread and ExitProcess.
*/
void
EVENT_Set
(
K32OBJ
*
obj
)
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
SYSTEM_LOCK
();
event
->
signaled
=
TRUE
;
SYNC_WakeUp
(
&
event
->
wait_queue
,
event
->
manual_reset
?
INFINITE32
:
1
);
SYSTEM_UNLOCK
();
}
/***********************************************************************
* EVENT_Create
*
* Partial implementation of CreateEvent.
* Used internally by processes and threads.
*/
K32OBJ
*
EVENT_Create
(
BOOL32
manual_reset
,
BOOL32
initial_state
)
{
EVENT
*
event
;
SYSTEM_LOCK
();
if
((
event
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
*
event
)
)))
{
event
->
header
.
type
=
K32OBJ_EVENT
;
event
->
header
.
refcount
=
1
;
event
->
wait_queue
=
NULL
;
event
->
manual_reset
=
manual_reset
;
event
->
signaled
=
initial_state
;
}
SYSTEM_UNLOCK
();
return
event
?
&
event
->
header
:
NULL
;
}
/***********************************************************************
* CreateEvent32A (KERNEL32.156)
*/
HANDLE32
WINAPI
CreateEvent32A
(
SECURITY_ATTRIBUTES
*
sa
,
BOOL32
manual_reset
,
...
...
@@ -99,20 +47,15 @@ HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset,
CLIENT_SendRequest
(
REQ_CREATE_EVENT
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
==
-
1
)
return
NULL
;
if
(
reply
.
handle
==
-
1
)
return
0
;
SYSTEM_LOCK
();
event
=
(
EVENT
*
)
K32OBJ_Create
(
K32OBJ_EVENT
,
sizeof
(
*
event
),
name
,
reply
.
handle
,
EVENT_ALL_ACCESS
,
sa
,
&
handle
);
if
(
event
)
{
/* Finish initializing it */
event
->
wait_queue
=
NULL
;
event
->
manual_reset
=
manual_reset
;
event
->
signaled
=
initial_state
;
K32OBJ_DecCount
(
&
event
->
header
);
}
SYSTEM_UNLOCK
();
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
return
handle
;
}
...
...
@@ -145,13 +88,29 @@ HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name )
{
HANDLE32
handle
=
0
;
K32OBJ
*
obj
;
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_EVENT
))
!=
NULL
)
struct
open_named_obj_request
req
;
struct
open_named_obj_reply
reply
;
int
len
=
name
?
strlen
(
name
)
+
1
:
0
;
req
.
type
=
OPEN_EVENT
;
req
.
access
=
access
;
req
.
inherit
=
inherit
;
CLIENT_SendRequest
(
REQ_OPEN_NAMED_OBJ
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
!=
-
1
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
-
1
);
K32OBJ_DecCount
(
obj
);
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_EVENT
))
!=
NULL
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
reply
.
handle
);
K32OBJ_DecCount
(
obj
);
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
/* must return 0 on failure, not -1 */
}
else
CLIENT_CloseHandle
(
reply
.
handle
);
SYSTEM_UNLOCK
();
}
SYSTEM_UNLOCK
();
return
handle
;
}
...
...
@@ -169,144 +128,47 @@ HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name )
/***********************************************************************
* PulseEvent (KERNEL32.557)
*/
BOOL32
WINAPI
PulseEvent
(
HANDLE32
handle
)
{
struct
event_op_request
req
;
EVENT
*
event
;
SYSTEM_LOCK
();
if
(
!
(
event
=
(
EVENT
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handle
,
K32OBJ_EVENT
,
EVENT_MODIFY_STATE
,
&
req
.
handle
)))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
if
(
req
.
handle
!=
-
1
)
{
SYSTEM_UNLOCK
();
req
.
op
=
PULSE_EVENT
;
CLIENT_SendRequest
(
REQ_EVENT_OP
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
event
->
signaled
=
TRUE
;
SYNC_WakeUp
(
&
event
->
wait_queue
,
event
->
manual_reset
?
INFINITE32
:
1
);
event
->
signaled
=
FALSE
;
K32OBJ_DecCount
(
&
event
->
header
);
SYSTEM_UNLOCK
();
return
TRUE
;
}
/***********************************************************************
* SetEvent (KERNEL32.644)
*/
BOOL32
WINAPI
SetEvent
(
HANDLE32
handle
)
{
struct
event_op_request
req
;
EVENT
*
event
;
SYSTEM_LOCK
();
if
(
!
(
event
=
(
EVENT
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handle
,
K32OBJ_EVENT
,
EVENT_MODIFY_STATE
,
&
req
.
handle
)))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
if
(
req
.
handle
!=
-
1
)
{
SYSTEM_UNLOCK
();
req
.
op
=
SET_EVENT
;
CLIENT_SendRequest
(
REQ_EVENT_OP
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
event
->
signaled
=
TRUE
;
SYNC_WakeUp
(
&
event
->
wait_queue
,
event
->
manual_reset
?
INFINITE32
:
1
);
K32OBJ_DecCount
(
&
event
->
header
);
SYSTEM_UNLOCK
();
return
TRUE
;
}
/***********************************************************************
* ResetEvent (KERNEL32.586)
* EVENT_Operation
*
* Execute an event operation (set,reset,pulse).
*/
BOOL32
WINAPI
ResetEvent
(
HANDLE32
handle
)
static
BOOL32
EVENT_Operation
(
HANDLE32
handle
,
enum
event_op
op
)
{
struct
event_op_request
req
;
EVENT
*
event
;
SYSTEM_LOCK
();
if
(
!
(
event
=
(
EVENT
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handle
,
K32OBJ_EVENT
,
EVENT_MODIFY_STATE
,
&
req
.
handle
)))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
if
(
req
.
handle
!=
-
1
)
{
SYSTEM_UNLOCK
();
req
.
op
=
RESET_EVENT
;
CLIENT_SendRequest
(
REQ_EVENT_OP
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
event
->
signaled
=
FALSE
;
K32OBJ_DecCount
(
&
event
->
header
);
SYSTEM_UNLOCK
();
return
TRUE
;
}
/***********************************************************************
* EVENT_Signaled
*/
static
BOOL32
EVENT_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
return
event
->
signaled
;
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_EVENT
,
EVENT_MODIFY_STATE
);
if
(
req
.
handle
==
-
1
)
return
FALSE
;
req
.
op
=
op
;
CLIENT_SendRequest
(
REQ_EVENT_OP
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
/***********************************************************************
* EVENT_Satisfied
*
* Wait on this object has been satisfied.
* PulseEvent (KERNEL32.557)
*/
static
BOOL32
EVENT_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
BOOL32
WINAPI
PulseEvent
(
HANDLE32
handle
)
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
/* Reset if it's an auto-reset event */
if
(
!
event
->
manual_reset
)
event
->
signaled
=
FALSE
;
return
FALSE
;
/* Not abandoned */
return
EVENT_Operation
(
handle
,
PULSE_EVENT
);
}
/***********************************************************************
* EVENT_AddWait
*
* Add thread to object wait queue.
* SetEvent (KERNEL32.644)
*/
static
void
EVENT_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
BOOL32
WINAPI
SetEvent
(
HANDLE32
handle
)
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
THREAD_AddQueue
(
&
event
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
return
EVENT_Operation
(
handle
,
SET_EVENT
);
}
/***********************************************************************
* EVENT_RemoveWait
*
* Remove thread from object wait queue.
* ResetEvent (KERNEL32.586)
*/
static
void
EVENT_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
BOOL32
WINAPI
ResetEvent
(
HANDLE32
handle
)
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
THREAD_RemoveQueue
(
&
event
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
return
EVENT_Operation
(
handle
,
RESET_EVENT
);
}
...
...
@@ -317,8 +179,6 @@ static void EVENT_Destroy( K32OBJ *obj )
{
EVENT
*
event
=
(
EVENT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_EVENT
);
/* There cannot be any thread on the list since the ref count is 0 */
assert
(
event
->
wait_queue
==
NULL
);
obj
->
type
=
K32OBJ_UNKNOWN
;
HeapFree
(
SystemHeap
,
0
,
event
);
}
...
...
scheduler/handle.c
View file @
55443878
...
...
@@ -192,6 +192,27 @@ K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
/***********************************************************************
* HANDLE_GetServerHandle
*
* Retrieve the server handle associated to an object.
*/
int
HANDLE_GetServerHandle
(
PDB32
*
pdb
,
HANDLE32
handle
,
K32OBJ_TYPE
type
,
DWORD
access
)
{
int
server_handle
;
K32OBJ
*
obj
;
SYSTEM_LOCK
();
if
((
obj
=
HANDLE_GetObjPtr
(
pdb
,
handle
,
type
,
access
,
&
server_handle
)))
K32OBJ_DecCount
(
obj
);
else
server_handle
=
-
1
;
SYSTEM_UNLOCK
();
return
server_handle
;
}
/***********************************************************************
* HANDLE_SetObjPtr
*
* Change the object pointer of a handle, and increment the refcount.
...
...
@@ -413,3 +434,38 @@ done:
SYSTEM_UNLOCK
();
return
ret
;
}
/***********************************************************************
* ConvertToGlobalHandle (KERNEL32)
*/
HANDLE32
WINAPI
ConvertToGlobalHandle
(
HANDLE32
hSrc
)
{
int
src_handle
,
dst_handle
;
HANDLE32
handle
;
K32OBJ
*
obj
=
NULL
;
DWORD
access
;
if
(
HANDLE_IS_GLOBAL
(
hSrc
))
return
hSrc
;
if
(
!
(
obj
=
HANDLE_GetObjPtr
(
PROCESS_Current
(),
hSrc
,
K32OBJ_UNKNOWN
,
0
,
&
src_handle
)))
return
0
;
HANDLE_GetAccess
(
PROCESS_Current
(),
hSrc
,
&
access
);
if
(
src_handle
!=
-
1
)
dst_handle
=
CLIENT_DuplicateHandle
(
GetCurrentProcess
(),
src_handle
,
-
1
,
-
1
,
0
,
FALSE
,
DUP_HANDLE_MAKE_GLOBAL
|
DUP_HANDLE_SAME_ACCESS
);
else
dst_handle
=
-
1
;
if
((
handle
=
HANDLE_Alloc
(
PROCESS_Initial
(),
obj
,
access
,
FALSE
,
dst_handle
))
!=
INVALID_HANDLE_VALUE32
)
handle
=
HANDLE_LOCAL_TO_GLOBAL
(
handle
);
else
handle
=
0
;
CloseHandle
(
hSrc
);
return
handle
;
}
scheduler/k32obj.c
View file @
55443878
...
...
@@ -12,7 +12,6 @@
/* The declarations are here to avoid including a lot of unnecessary files */
extern
const
K32OBJ_OPS
CRITICAL_SECTION_Ops
;
extern
const
K32OBJ_OPS
PROCESS_Ops
;
extern
const
K32OBJ_OPS
THREAD_Ops
;
extern
const
K32OBJ_OPS
FILE_Ops
;
...
...
@@ -30,12 +29,6 @@ extern const K32OBJ_OPS PIPE_Ops;
static
const
K32OBJ_OPS
K32OBJ_NullOps
=
{
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
NULL
/* destroy */
};
...
...
@@ -45,7 +38,7 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
&
SEMAPHORE_Ops
,
/* K32OBJ_SEMAPHORE */
&
EVENT_Ops
,
/* K32OBJ_EVENT */
&
MUTEX_Ops
,
/* K32OBJ_MUTEX */
&
CRITICAL_SECTION_Ops
,
/* K32OBJ_CRITICAL_SECTION */
&
K32OBJ_NullOps
,
/* K32OBJ_CRITICAL_SECTION */
&
PROCESS_Ops
,
/* K32OBJ_PROCESS */
&
THREAD_Ops
,
/* K32OBJ_THREAD */
&
FILE_Ops
,
/* K32OBJ_FILE */
...
...
scheduler/mutex.c
View file @
55443878
...
...
@@ -17,67 +17,17 @@
typedef
struct
_MUTEX
{
K32OBJ
header
;
THREAD_QUEUE
wait_queue
;
DWORD
owner
;
DWORD
count
;
BOOL32
abandoned
;
struct
_MUTEX
*
next
;
struct
_MUTEX
*
prev
;
}
MUTEX
;
static
BOOL32
MUTEX_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
MUTEX_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
MUTEX_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
MUTEX_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
MUTEX_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
MUTEX_Ops
=
{
MUTEX_Signaled
,
/* signaled */
MUTEX_Satisfied
,
/* satisfied */
MUTEX_AddWait
,
/* add_wait */
MUTEX_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
MUTEX_Destroy
/* destroy */
};
/***********************************************************************
* MUTEX_Release
*
* Release a mutex once the count is 0.
* Helper function for MUTEX_Abandon and ReleaseMutex.
*/
static
void
MUTEX_Release
(
MUTEX
*
mutex
)
{
/* Remove the mutex from the thread list of owned mutexes */
if
(
mutex
->
next
)
mutex
->
next
->
prev
=
mutex
->
prev
;
if
(
mutex
->
prev
)
mutex
->
prev
->
next
=
mutex
->
next
;
else
THREAD_Current
()
->
mutex_list
=
&
mutex
->
next
->
header
;
mutex
->
next
=
mutex
->
prev
=
NULL
;
mutex
->
owner
=
0
;
SYNC_WakeUp
(
&
mutex
->
wait_queue
,
INFINITE32
);
}
/***********************************************************************
* MUTEX_Abandon
*
* Abandon a mutex.
*/
void
MUTEX_Abandon
(
K32OBJ
*
obj
)
{
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
assert
(
mutex
->
count
&&
(
mutex
->
owner
==
GetCurrentThreadId
())
);
mutex
->
count
=
0
;
mutex
->
abandoned
=
TRUE
;
MUTEX_Release
(
mutex
);
}
/***********************************************************************
* CreateMutex32A (KERNEL32.166)
*/
HANDLE32
WINAPI
CreateMutex32A
(
SECURITY_ATTRIBUTES
*
sa
,
BOOL32
owner
,
...
...
@@ -95,37 +45,14 @@ HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
CLIENT_SendRequest
(
REQ_CREATE_MUTEX
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
==
-
1
)
return
NULL
;
if
(
reply
.
handle
==
-
1
)
return
0
;
SYSTEM_LOCK
();
mutex
=
(
MUTEX
*
)
K32OBJ_Create
(
K32OBJ_MUTEX
,
sizeof
(
*
mutex
),
name
,
reply
.
handle
,
MUTEX_ALL_ACCESS
,
sa
,
&
handle
);
if
(
mutex
)
{
/* Finish initializing it */
mutex
->
wait_queue
=
NULL
;
mutex
->
abandoned
=
FALSE
;
mutex
->
prev
=
NULL
;
if
(
owner
)
{
K32OBJ
**
list
;
mutex
->
owner
=
GetCurrentThreadId
();
mutex
->
count
=
1
;
/* Add the mutex in the thread list of owned mutexes */
list
=
&
THREAD_Current
()
->
mutex_list
;
if
((
mutex
->
next
=
(
MUTEX
*
)
*
list
))
mutex
->
next
->
prev
=
mutex
;
*
list
=
&
mutex
->
header
;
}
else
{
mutex
->
owner
=
0
;
mutex
->
count
=
0
;
mutex
->
next
=
NULL
;
}
K32OBJ_DecCount
(
&
mutex
->
header
);
}
SetLastError
(
0
);
/* FIXME */
if
(
mutex
)
K32OBJ_DecCount
(
&
mutex
->
header
);
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
SYSTEM_UNLOCK
();
return
handle
;
}
...
...
@@ -151,13 +78,29 @@ HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name )
{
HANDLE32
handle
=
0
;
K32OBJ
*
obj
;
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_MUTEX
))
!=
NULL
)
struct
open_named_obj_request
req
;
struct
open_named_obj_reply
reply
;
int
len
=
name
?
strlen
(
name
)
+
1
:
0
;
req
.
type
=
OPEN_MUTEX
;
req
.
access
=
access
;
req
.
inherit
=
inherit
;
CLIENT_SendRequest
(
REQ_OPEN_NAMED_OBJ
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
!=
-
1
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
-
1
);
K32OBJ_DecCount
(
obj
);
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_MUTEX
))
!=
NULL
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
reply
.
handle
);
K32OBJ_DecCount
(
obj
);
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
/* must return 0 on failure, not -1 */
}
else
CLIENT_CloseHandle
(
reply
.
handle
);
SYSTEM_UNLOCK
();
}
SYSTEM_UNLOCK
();
return
handle
;
}
...
...
@@ -180,95 +123,12 @@ HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name )
BOOL32
WINAPI
ReleaseMutex
(
HANDLE32
handle
)
{
struct
release_mutex_request
req
;
MUTEX
*
mutex
;
SYSTEM_LOCK
();
if
(
!
(
mutex
=
(
MUTEX
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handle
,
K32OBJ_MUTEX
,
MUTEX_MODIFY_STATE
,
&
req
.
handle
)))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
if
(
req
.
handle
!=
-
1
)
{
SYSTEM_UNLOCK
();
CLIENT_SendRequest
(
REQ_RELEASE_MUTEX
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
if
(
!
mutex
->
count
||
(
mutex
->
owner
!=
GetCurrentThreadId
()))
{
SYSTEM_UNLOCK
();
SetLastError
(
ERROR_NOT_OWNER
);
return
FALSE
;
}
if
(
!--
mutex
->
count
)
MUTEX_Release
(
mutex
);
K32OBJ_DecCount
(
&
mutex
->
header
);
SYSTEM_UNLOCK
();
return
TRUE
;
}
/***********************************************************************
* MUTEX_Signaled
*/
static
BOOL32
MUTEX_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
return
(
!
mutex
->
count
||
(
mutex
->
owner
==
thread_id
));
}
/***********************************************************************
* MUTEX_Satisfied
*
* Wait on this object has been satisfied.
*/
static
BOOL32
MUTEX_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
BOOL32
ret
;
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
assert
(
!
mutex
->
count
||
(
mutex
->
owner
==
thread_id
)
);
mutex
->
owner
=
thread_id
;
if
(
!
mutex
->
count
++
)
{
/* Add the mutex in the thread list of owned mutexes */
K32OBJ
**
list
=
&
THREAD_ID_TO_THDB
(
thread_id
)
->
mutex_list
;
assert
(
!
mutex
->
next
);
if
((
mutex
->
next
=
(
MUTEX
*
)
*
list
))
mutex
->
next
->
prev
=
mutex
;
*
list
=
&
mutex
->
header
;
mutex
->
prev
=
NULL
;
}
ret
=
mutex
->
abandoned
;
mutex
->
abandoned
=
FALSE
;
return
ret
;
}
/***********************************************************************
* MUTEX_AddWait
*
* Add a thread to the object wait queue.
*/
static
void
MUTEX_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
THREAD_AddQueue
(
&
mutex
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/***********************************************************************
* MUTEX_RemoveWait
*
* Remove a thread from the object wait queue.
*/
static
void
MUTEX_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
THREAD_RemoveQueue
(
&
mutex
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_MUTEX
,
MUTEX_MODIFY_STATE
);
if
(
req
.
handle
==
-
1
)
return
FALSE
;
CLIENT_SendRequest
(
REQ_RELEASE_MUTEX
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
...
...
@@ -279,8 +139,6 @@ static void MUTEX_Destroy( K32OBJ *obj )
{
MUTEX
*
mutex
=
(
MUTEX
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_MUTEX
);
/* There cannot be any thread on the list since the ref count is 0 */
assert
(
mutex
->
wait_queue
==
NULL
);
obj
->
type
=
K32OBJ_UNKNOWN
;
HeapFree
(
SystemHeap
,
0
,
mutex
);
}
scheduler/pipe.c
View file @
55443878
...
...
@@ -23,12 +23,6 @@ static void PIPE_Destroy( K32OBJ *obj );
const
K32OBJ_OPS
PIPE_Ops
=
{
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
PIPE_Destroy
/* destroy */
};
...
...
scheduler/process.c
View file @
55443878
...
...
@@ -23,20 +23,10 @@
#include "server.h"
#include "debug.h"
static
BOOL32
PROCESS_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
PROCESS_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
PROCESS_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
PROCESS_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
PROCESS_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
PROCESS_Ops
=
{
PROCESS_Signaled
,
/* signaled */
PROCESS_Satisfied
,
/* satisfied */
PROCESS_AddWait
,
/* add_wait */
PROCESS_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
PROCESS_Destroy
/* destroy */
};
...
...
@@ -295,8 +285,6 @@ static void PROCESS_FreePDB( PDB32 *pdb )
if
(
pdb
->
handle_table
)
HANDLE_CloseAll
(
pdb
,
NULL
);
ENV_FreeEnvironment
(
pdb
);
if
(
pdb
->
heap
&&
(
pdb
->
heap
!=
pdb
->
system_heap
))
HeapDestroy
(
pdb
->
heap
);
if
(
pdb
->
load_done_evt
)
K32OBJ_DecCount
(
pdb
->
load_done_evt
);
if
(
pdb
->
event
)
K32OBJ_DecCount
(
pdb
->
event
);
DeleteCriticalSection
(
&
pdb
->
crit_section
);
HeapFree
(
SystemHeap
,
0
,
pdb
);
}
...
...
@@ -325,19 +313,11 @@ static PDB32 *PROCESS_CreatePDB( PDB32 *parent )
pdb
->
priority
=
8
;
/* Normal */
pdb
->
heap
=
pdb
->
system_heap
;
/* will be changed later on */
InitializeCriticalSection
(
&
pdb
->
crit_section
);
/* Allocate the events */
if
(
!
(
pdb
->
event
=
EVENT_Create
(
TRUE
,
FALSE
)))
goto
error
;
if
(
!
(
pdb
->
load_done_evt
=
EVENT_Create
(
TRUE
,
FALSE
)))
goto
error
;
/* Create the handle table */
if
(
!
HANDLE_CreateTable
(
pdb
,
TRUE
))
goto
error
;
PROCESS_PDBList_Insert
(
pdb
);
return
pdb
;
error:
...
...
@@ -347,6 +327,21 @@ error:
/***********************************************************************
* PROCESS_FinishCreatePDB
*
* Second part of CreatePDB
*/
static
BOOL32
PROCESS_FinishCreatePDB
(
PDB32
*
pdb
)
{
InitializeCriticalSection
(
&
pdb
->
crit_section
);
/* Allocate the event */
if
(
!
(
pdb
->
load_done_evt
=
CreateEvent32A
(
NULL
,
TRUE
,
FALSE
,
NULL
)))
return
FALSE
;
return
TRUE
;
}
/***********************************************************************
* PROCESS_Init
*/
BOOL32
PROCESS_Init
(
void
)
...
...
@@ -357,9 +352,8 @@ BOOL32 PROCESS_Init(void)
/* Initialize virtual memory management */
if
(
!
VIRTUAL_Init
())
return
FALSE
;
/* Create the system
and SEGPTR
heaps */
/* Create the system heaps */
if
(
!
(
SystemHeap
=
HeapCreate
(
HEAP_GROWABLE
,
0x10000
,
0
)))
return
FALSE
;
if
(
!
(
SegptrHeap
=
HeapCreate
(
HEAP_WINE_SEGPTR
,
0
,
0
)))
return
FALSE
;
/* Create the initial process and thread structures */
if
(
!
(
pdb
=
PROCESS_CreatePDB
(
NULL
)))
return
FALSE
;
...
...
@@ -376,6 +370,10 @@ BOOL32 PROCESS_Init(void)
/* Initialize the first thread */
if
(
CLIENT_InitThread
())
return
FALSE
;
if
(
!
PROCESS_FinishCreatePDB
(
pdb
))
return
FALSE
;
/* Create the SEGPTR heap */
if
(
!
(
SegptrHeap
=
HeapCreate
(
HEAP_WINE_SEGPTR
,
0
,
0
)))
return
FALSE
;
return
TRUE
;
}
...
...
@@ -400,6 +398,7 @@ PDB32 *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if
(
!
pdb
)
return
NULL
;
info
->
hThread
=
info
->
hProcess
=
INVALID_HANDLE_VALUE32
;
if
(
!
PROCESS_FinishCreatePDB
(
pdb
))
goto
error
;
/* Create the heap */
...
...
@@ -473,56 +472,6 @@ error:
/***********************************************************************
* PROCESS_Signaled
*/
static
BOOL32
PROCESS_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
PDB32
*
pdb
=
(
PDB32
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_PROCESS
);
return
K32OBJ_OPS
(
pdb
->
event
)
->
signaled
(
pdb
->
event
,
thread_id
);
}
/***********************************************************************
* PROCESS_Satisfied
*
* Wait on this object has been satisfied.
*/
static
BOOL32
PROCESS_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
PDB32
*
pdb
=
(
PDB32
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_PROCESS
);
return
K32OBJ_OPS
(
pdb
->
event
)
->
satisfied
(
pdb
->
event
,
thread_id
);
}
/***********************************************************************
* PROCESS_AddWait
*
* Add thread to object wait queue.
*/
static
void
PROCESS_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
PDB32
*
pdb
=
(
PDB32
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_PROCESS
);
return
K32OBJ_OPS
(
pdb
->
event
)
->
add_wait
(
pdb
->
event
,
thread_id
);
}
/***********************************************************************
* PROCESS_RemoveWait
*
* Remove thread from object wait queue.
*/
static
void
PROCESS_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
PDB32
*
pdb
=
(
PDB32
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_PROCESS
);
return
K32OBJ_OPS
(
pdb
->
event
)
->
remove_wait
(
pdb
->
event
,
thread_id
);
}
/***********************************************************************
* PROCESS_Destroy
*/
static
void
PROCESS_Destroy
(
K32OBJ
*
ptr
)
...
...
@@ -552,7 +501,6 @@ void WINAPI ExitProcess( DWORD status )
SYSTEM_LOCK
();
/* FIXME: should kill all running threads of this process */
pdb
->
exit_code
=
status
;
EVENT_Set
(
pdb
->
event
);
if
(
pdb
->
console
)
FreeConsole
();
SYSTEM_UNLOCK
();
...
...
@@ -566,13 +514,13 @@ void WINAPI ExitProcess( DWORD status )
*/
BOOL32
WINAPI
TerminateProcess
(
HANDLE32
handle
,
DWORD
exit_code
)
{
int
server_handle
;
BOOL32
ret
;
PDB32
*
pdb
=
PROCESS_GetPtr
(
handle
,
PROCESS_TERMINATE
,
&
server_handle
);
if
(
!
pdb
)
return
FALSE
;
re
t
=
!
CLIENT_TerminateProcess
(
server_handle
,
exit_code
)
;
K32OBJ_DecCount
(
&
pdb
->
header
);
return
ret
;
struct
terminate_process_request
req
;
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_PROCESS
,
PROCESS_TERMINATE
)
;
re
q
.
exit_code
=
exit_code
;
CLIENT_SendRequest
(
REQ_TERMINATE_PROCESS
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
)
;
}
/***********************************************************************
...
...
@@ -832,8 +780,8 @@ BOOL32 WINAPI GetProcessWorkingSetSize(HANDLE32 hProcess,LPDWORD minset,
* It really shouldn't be here, but I'll move it when it's been checked!
*/
#define SHUTDOWN_NORETRY 1
extern
unsigned
int
shutdown_noretry
=
0
;
extern
unsigned
int
shutdown_priority
=
0x280L
;
static
unsigned
int
shutdown_noretry
=
0
;
static
unsigned
int
shutdown_priority
=
0x280L
;
BOOL32
WINAPI
SetProcessShutdownParameters
(
DWORD
level
,
DWORD
flags
)
{
if
(
flags
&
SHUTDOWN_NORETRY
)
...
...
@@ -901,28 +849,6 @@ BOOL32 WINAPI WriteProcessMemory(HANDLE32 hProcess, LPVOID lpBaseAddress,
}
/***********************************************************************
* ConvertToGlobalHandle (KERNEL32)
*/
HANDLE32
WINAPI
ConvertToGlobalHandle
(
HANDLE32
hSrc
)
{
HANDLE32
hProcessInit
,
hDest
;
/* Get a handle to the initial process */
hProcessInit
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
PROCESS_InitialProcessID
);
/* Duplicate the handle into the initial process */
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
hSrc
,
hProcessInit
,
&
hDest
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
|
DUPLICATE_CLOSE_SOURCE
)
)
hDest
=
0
;
/* Close initial process handle */
CloseHandle
(
hProcessInit
);
/* Return obfuscated global handle */
return
hDest
?
HANDLE_LOCAL_TO_GLOBAL
(
hDest
)
:
0
;
}
/***********************************************************************
* RegisterServiceProcess (KERNEL, KERNEL32)
*
* A service process calls this function to ensure that it continues to run
...
...
@@ -942,28 +868,17 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* FIXME
* Should call SetLastError (but doesn't).
*/
BOOL32
WINAPI
GetExitCodeProcess
(
HANDLE32
hProcess
,
/* [I] handle to the process */
LPDWORD
lpExitCode
)
/* [O] address to receive termination status */
{
PDB32
*
process
;
int
server_handle
;
struct
get_process_info_reply
info
;
int
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
hProcess
,
K32OBJ_PROCESS
,
PROCESS_QUERY_INFORMATION
);
if
(
!
(
process
=
PROCESS_GetPtr
(
hProcess
,
PROCESS_QUERY_INFORMATION
,
&
server_handle
)))
return
FALSE
;
if
(
server_handle
!=
-
1
)
{
CLIENT_GetProcessInfo
(
server_handle
,
&
info
);
if
(
lpExitCode
)
*
lpExitCode
=
info
.
exit_code
;
}
else
if
(
lpExitCode
)
*
lpExitCode
=
process
->
exit_code
;
K32OBJ_DecCount
(
&
process
->
header
);
if
(
CLIENT_GetProcessInfo
(
handle
,
&
info
))
return
FALSE
;
if
(
lpExitCode
)
*
lpExitCode
=
info
.
exit_code
;
return
TRUE
;
}
...
...
scheduler/semaphore.c
View file @
55443878
...
...
@@ -17,25 +17,12 @@
typedef
struct
{
K32OBJ
header
;
THREAD_QUEUE
wait_queue
;
LONG
count
;
LONG
max
;
}
SEMAPHORE
;
static
BOOL32
SEMAPHORE_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
SEMAPHORE_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
SEMAPHORE_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
SEMAPHORE_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
SEMAPHORE_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
SEMAPHORE_Ops
=
{
SEMAPHORE_Signaled
,
/* signaled */
SEMAPHORE_Satisfied
,
/* satisfied */
SEMAPHORE_AddWait
,
/* add_wait */
SEMAPHORE_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
SEMAPHORE_Destroy
/* destroy */
};
...
...
@@ -57,7 +44,7 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
if
((
max
<=
0
)
||
(
initial
<
0
)
||
(
initial
>
max
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
INVALID_HANDLE_VALUE32
;
return
0
;
}
req
.
initial
=
(
unsigned
int
)
initial
;
...
...
@@ -67,21 +54,15 @@ HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
CLIENT_SendRequest
(
REQ_CREATE_SEMAPHORE
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
==
-
1
)
return
NULL
;
if
(
reply
.
handle
==
-
1
)
return
0
;
SYSTEM_LOCK
();
sem
=
(
SEMAPHORE
*
)
K32OBJ_Create
(
K32OBJ_SEMAPHORE
,
sizeof
(
*
sem
),
name
,
reply
.
handle
,
SEMAPHORE_ALL_ACCESS
,
sa
,
&
handle
);
if
(
sem
)
{
/* Finish initializing it */
sem
->
wait_queue
=
NULL
;
sem
->
count
=
initial
;
sem
->
max
=
max
;
K32OBJ_DecCount
(
&
sem
->
header
);
}
if
(
sem
)
K32OBJ_DecCount
(
&
sem
->
header
);
SYSTEM_UNLOCK
();
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
return
handle
;
}
...
...
@@ -106,13 +87,29 @@ HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
{
HANDLE32
handle
=
0
;
K32OBJ
*
obj
;
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_SEMAPHORE
))
!=
NULL
)
struct
open_named_obj_request
req
;
struct
open_named_obj_reply
reply
;
int
len
=
name
?
strlen
(
name
)
+
1
:
0
;
req
.
type
=
OPEN_SEMAPHORE
;
req
.
access
=
access
;
req
.
inherit
=
inherit
;
CLIENT_SendRequest
(
REQ_OPEN_NAMED_OBJ
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
name
,
len
);
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
);
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
reply
.
handle
!=
-
1
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
-
1
);
K32OBJ_DecCount
(
obj
);
SYSTEM_LOCK
();
if
((
obj
=
K32OBJ_FindNameType
(
name
,
K32OBJ_SEMAPHORE
))
!=
NULL
)
{
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
obj
,
access
,
inherit
,
reply
.
handle
);
K32OBJ_DecCount
(
obj
);
if
(
handle
==
INVALID_HANDLE_VALUE32
)
handle
=
0
;
/* must return 0 on failure, not -1 */
}
else
CLIENT_CloseHandle
(
reply
.
handle
);
SYSTEM_UNLOCK
();
}
SYSTEM_UNLOCK
();
return
handle
;
}
...
...
@@ -135,111 +132,27 @@ HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
BOOL32
WINAPI
ReleaseSemaphore
(
HANDLE32
handle
,
LONG
count
,
LONG
*
previous
)
{
struct
release_semaphore_request
req
;
SEMAPHORE
*
sem
;
struct
release_semaphore_reply
reply
;
int
len
;
if
(
count
<
0
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
SYSTEM_LOCK
();
if
(
!
(
sem
=
(
SEMAPHORE
*
)
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handle
,
K32OBJ_SEMAPHORE
,
SEMAPHORE_MODIFY_STATE
,
&
req
.
handle
)))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
if
(
req
.
handle
!=
-
1
)
{
struct
release_semaphore_reply
reply
;
int
len
;
SYSTEM_UNLOCK
();
req
.
count
=
(
unsigned
int
)
count
;
CLIENT_SendRequest
(
REQ_RELEASE_SEMAPHORE
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
if
(
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
))
return
FALSE
;
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
previous
)
*
previous
=
reply
.
prev_count
;
return
TRUE
;
}
if
(
previous
)
*
previous
=
sem
->
count
;
if
(
sem
->
count
+
count
>
sem
->
max
)
{
SYSTEM_UNLOCK
();
SetLastError
(
ERROR_TOO_MANY_POSTS
);
return
FALSE
;
}
if
(
sem
->
count
>
0
)
{
/* There cannot be any thread waiting if the count is > 0 */
assert
(
sem
->
wait_queue
==
NULL
);
sem
->
count
+=
count
;
}
else
{
sem
->
count
=
count
;
SYNC_WakeUp
(
&
sem
->
wait_queue
,
count
);
}
K32OBJ_DecCount
(
&
sem
->
header
);
SYSTEM_UNLOCK
();
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_SEMAPHORE
,
SEMAPHORE_MODIFY_STATE
);
if
(
req
.
handle
==
-
1
)
return
FALSE
;
req
.
count
=
(
unsigned
int
)
count
;
CLIENT_SendRequest
(
REQ_RELEASE_SEMAPHORE
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
if
(
CLIENT_WaitReply
(
&
len
,
NULL
,
1
,
&
reply
,
sizeof
(
reply
)
))
return
FALSE
;
CHECK_LEN
(
len
,
sizeof
(
reply
)
);
if
(
previous
)
*
previous
=
reply
.
prev_count
;
return
TRUE
;
}
/***********************************************************************
* SEMAPHORE_Signaled
*/
static
BOOL32
SEMAPHORE_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
SEMAPHORE
*
sem
=
(
SEMAPHORE
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_SEMAPHORE
);
return
(
sem
->
count
>
0
);
}
/***********************************************************************
* SEMAPHORE_Satisfied
*
* Wait on this object has been satisfied.
*/
static
BOOL32
SEMAPHORE_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
SEMAPHORE
*
sem
=
(
SEMAPHORE
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_SEMAPHORE
);
assert
(
sem
->
count
>
0
);
sem
->
count
--
;
return
FALSE
;
/* Not abandoned */
}
/***********************************************************************
* SEMAPHORE_AddWait
*
* Add current thread to object wait queue.
*/
static
void
SEMAPHORE_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
SEMAPHORE
*
sem
=
(
SEMAPHORE
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_SEMAPHORE
);
THREAD_AddQueue
(
&
sem
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/***********************************************************************
* SEMAPHORE_RemoveWait
*
* Remove thread from object wait queue.
*/
static
void
SEMAPHORE_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
SEMAPHORE
*
sem
=
(
SEMAPHORE
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_SEMAPHORE
);
THREAD_RemoveQueue
(
&
sem
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/***********************************************************************
* SEMAPHORE_Destroy
*/
static
void
SEMAPHORE_Destroy
(
K32OBJ
*
obj
)
...
...
@@ -247,7 +160,6 @@ static void SEMAPHORE_Destroy( K32OBJ *obj )
SEMAPHORE
*
sem
=
(
SEMAPHORE
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_SEMAPHORE
);
/* There cannot be any thread on the list since the ref count is 0 */
assert
(
sem
->
wait_queue
==
NULL
);
obj
->
type
=
K32OBJ_UNKNOWN
;
HeapFree
(
SystemHeap
,
0
,
sem
);
}
scheduler/synchro.c
View file @
55443878
...
...
@@ -24,7 +24,7 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
BOOL32
wait_all
,
BOOL32
wait_msg
,
WAIT_STRUCT
*
wait
)
{
DWORD
i
,
j
;
DWORD
i
;
K32OBJ
**
ptr
;
SYSTEM_LOCK
();
...
...
@@ -32,7 +32,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
wait
->
signaled
=
WAIT_FAILED
;
wait
->
wait_all
=
wait_all
;
wait
->
wait_msg
=
wait_msg
;
wait
->
use_server
=
TRUE
;
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
count
;
i
++
,
ptr
++
)
{
if
(
!
(
*
ptr
=
HANDLE_GetObjPtr
(
PROCESS_Current
(),
handles
[
i
],
...
...
@@ -43,28 +42,11 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
break
;
}
if
(
wait
->
server
[
i
]
==
-
1
)
{
WARN
(
win32
,
"No server handle for %08x (type %d)
\n
"
,
handles
[
i
],
(
*
ptr
)
->
type
);
wait
->
use_server
=
FALSE
;
}
}
if
(
!
wait
->
use_server
)
{
for
(
j
=
0
,
ptr
=
wait
->
objs
;
j
<
i
;
j
++
,
ptr
++
)
{
if
(
!
K32OBJ_OPS
(
*
ptr
)
->
signaled
)
{
/* This object type cannot be waited upon */
ERR
(
win32
,
"Cannot wait on handle %08x
\n
"
,
handles
[
j
]);
break
;
}
}
}
else
j
=
count
;
if
((
i
!=
count
)
||
(
j
!=
count
))
if
(
i
!=
count
)
{
/* There was an error */
wait
->
wait_msg
=
FALSE
;
...
...
@@ -91,224 +73,6 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
/***********************************************************************
* SYNC_CheckCondition
*/
static
BOOL32
SYNC_CheckCondition
(
WAIT_STRUCT
*
wait
,
DWORD
thread_id
)
{
DWORD
i
;
K32OBJ
**
ptr
;
SYSTEM_LOCK
();
if
(
wait
->
wait_all
)
{
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
wait
->
count
;
i
++
,
ptr
++
)
{
if
(
!
K32OBJ_OPS
(
*
ptr
)
->
signaled
(
*
ptr
,
thread_id
))
{
SYSTEM_UNLOCK
();
return
FALSE
;
}
}
/* Wait satisfied: tell it to all objects */
wait
->
signaled
=
WAIT_OBJECT_0
;
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
wait
->
count
;
i
++
,
ptr
++
)
if
(
K32OBJ_OPS
(
*
ptr
)
->
satisfied
(
*
ptr
,
thread_id
))
wait
->
signaled
=
WAIT_ABANDONED_0
;
SYSTEM_UNLOCK
();
return
TRUE
;
}
else
{
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
wait
->
count
;
i
++
,
ptr
++
)
{
if
(
K32OBJ_OPS
(
*
ptr
)
->
signaled
(
*
ptr
,
thread_id
))
{
/* Wait satisfied: tell it to the object */
wait
->
signaled
=
WAIT_OBJECT_0
+
i
;
if
(
K32OBJ_OPS
(
*
ptr
)
->
satisfied
(
*
ptr
,
thread_id
))
wait
->
signaled
=
WAIT_ABANDONED_0
+
i
;
SYSTEM_UNLOCK
();
return
TRUE
;
}
}
SYSTEM_UNLOCK
();
return
FALSE
;
}
}
/***********************************************************************
* SYNC_WaitForCondition
*/
void
SYNC_WaitForCondition
(
WAIT_STRUCT
*
wait
,
DWORD
timeout
)
{
DWORD
i
,
thread_id
=
GetCurrentThreadId
();
LONG
count
;
K32OBJ
**
ptr
;
sigset_t
set
;
SYSTEM_LOCK
();
if
(
SYNC_CheckCondition
(
wait
,
thread_id
))
goto
done
;
/* Condition already satisfied */
if
(
!
timeout
)
{
/* No need to wait */
wait
->
signaled
=
WAIT_TIMEOUT
;
goto
done
;
}
/* Add ourselves to the waiting list of all objects */
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
wait
->
count
;
i
++
,
ptr
++
)
K32OBJ_OPS
(
*
ptr
)
->
add_wait
(
*
ptr
,
thread_id
);
/* Release the system lock completely */
count
=
SYSTEM_LOCK_COUNT
();
for
(
i
=
count
;
i
>
0
;
i
--
)
SYSTEM_UNLOCK
();
/* Now wait for it */
TRACE
(
win32
,
"starting wait (%p %04x)
\n
"
,
THREAD_Current
(),
THREAD_Current
()
->
teb_sel
);
sigprocmask
(
SIG_SETMASK
,
NULL
,
&
set
);
sigdelset
(
&
set
,
SIGUSR1
);
sigdelset
(
&
set
,
SIGALRM
);
if
(
timeout
!=
INFINITE32
)
{
while
(
wait
->
signaled
==
WAIT_FAILED
)
{
struct
itimerval
timer
;
DWORD
start_ticks
,
elapsed
;
timer
.
it_interval
.
tv_sec
=
timer
.
it_interval
.
tv_usec
=
0
;
timer
.
it_value
.
tv_sec
=
timeout
/
1000
;
timer
.
it_value
.
tv_usec
=
(
timeout
%
1000
)
*
1000
;
start_ticks
=
GetTickCount
();
setitimer
(
ITIMER_REAL
,
&
timer
,
NULL
);
sigsuspend
(
&
set
);
if
(
wait
->
signaled
!=
WAIT_FAILED
)
break
;
/* Recompute the timer value */
elapsed
=
GetTickCount
()
-
start_ticks
;
if
(
elapsed
>=
timeout
)
wait
->
signaled
=
WAIT_TIMEOUT
;
else
timeout
-=
elapsed
;
}
}
else
{
while
(
wait
->
signaled
==
WAIT_FAILED
)
{
sigsuspend
(
&
set
);
}
}
/* Grab the system lock again */
while
(
count
--
)
SYSTEM_LOCK
();
TRACE
(
win32
,
"wait finished (%p %04x)
\n
"
,
THREAD_Current
(),
THREAD_Current
()
->
teb_sel
);
/* Remove ourselves from the lists */
for
(
i
=
0
,
ptr
=
wait
->
objs
;
i
<
wait
->
count
;
i
++
,
ptr
++
)
K32OBJ_OPS
(
*
ptr
)
->
remove_wait
(
*
ptr
,
thread_id
);
done:
SYSTEM_UNLOCK
();
}
/***********************************************************************
* SYNC_DummySigHandler
*
* Dummy signal handler
*/
static
void
SYNC_DummySigHandler
(
void
)
{
}
/***********************************************************************
* SYNC_SetupSignals
*
* Setup signal handlers for a new thread.
* FIXME: should merge with SIGNAL_Init.
*/
void
SYNC_SetupSignals
(
void
)
{
sigset_t
set
;
SIGNAL_SetHandler
(
SIGUSR1
,
SYNC_DummySigHandler
,
0
);
/* FIXME: conflicts with system timers */
SIGNAL_SetHandler
(
SIGALRM
,
SYNC_DummySigHandler
,
0
);
sigemptyset
(
&
set
);
/* Make sure these are blocked by default */
sigaddset
(
&
set
,
SIGUSR1
);
sigaddset
(
&
set
,
SIGALRM
);
sigprocmask
(
SIG_BLOCK
,
&
set
,
NULL
);
}
/***********************************************************************
* SYNC_WakeUp
*/
void
SYNC_WakeUp
(
THREAD_QUEUE
*
wait_queue
,
DWORD
max
)
{
THREAD_ENTRY
*
entry
;
if
(
!
max
)
max
=
INFINITE32
;
SYSTEM_LOCK
();
if
(
!*
wait_queue
)
{
SYSTEM_UNLOCK
();
return
;
}
entry
=
(
*
wait_queue
)
->
next
;
for
(;;)
{
THDB
*
thdb
=
entry
->
thread
;
if
(
SYNC_CheckCondition
(
&
thdb
->
wait_struct
,
THDB_TO_THREAD_ID
(
thdb
)
))
{
TRACE
(
win32
,
"waking up %04x (pid %d)
\n
"
,
thdb
->
teb_sel
,
thdb
->
unix_pid
);
if
(
thdb
->
unix_pid
)
kill
(
thdb
->
unix_pid
,
SIGUSR1
);
else
FIXME
(
win32
,
"have got unix_pid 0
\n
"
);
if
(
!--
max
)
break
;
}
if
(
entry
==
*
wait_queue
)
break
;
entry
=
entry
->
next
;
}
SYSTEM_UNLOCK
();
}
/***********************************************************************
* SYNC_MsgWakeUp
*/
void
SYNC_MsgWakeUp
(
THDB
*
thdb
)
{
SYSTEM_LOCK
();
if
(
!
thdb
)
{
SYSTEM_UNLOCK
();
return
;
}
if
(
thdb
->
wait_struct
.
wait_msg
)
{
thdb
->
wait_struct
.
signaled
=
thdb
->
wait_struct
.
count
;
TRACE
(
win32
,
"waking up %04x for message
\n
"
,
thdb
->
teb_sel
);
if
(
thdb
->
unix_pid
)
kill
(
thdb
->
unix_pid
,
SIGUSR1
);
else
FIXME
(
win32
,
"have got unix_pid 0
\n
"
);
}
SYSTEM_UNLOCK
();
}
/***********************************************************************
* SYNC_DoWait
*/
DWORD
SYNC_DoWait
(
DWORD
count
,
const
HANDLE32
*
handles
,
...
...
@@ -326,30 +90,18 @@ DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
if
(
alertable
)
FIXME
(
win32
,
"alertable not implemented
\n
"
);
SYSTEM_LOCK
();
if
(
!
SYNC_BuildWaitStruct
(
count
,
handles
,
wait_all
,
wait_msg
,
wait
))
wait
->
signaled
=
WAIT_FAILED
;
else
{
/* Check if we can use a server wait */
if
(
wait
->
use_server
)
{
int
flags
=
0
;
SYSTEM_UNLOCK
();
if
(
wait_all
)
flags
|=
SELECT_ALL
;
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
if
(
wait_msg
)
flags
|=
SELECT_MSG
;
if
(
timeout
!=
INFINITE32
)
flags
|=
SELECT_TIMEOUT
;
return
CLIENT_Select
(
count
,
wait
->
server
,
flags
,
timeout
);
}
else
{
/* Now wait for it */
SYNC_WaitForCondition
(
wait
,
timeout
);
SYNC_FreeWaitStruct
(
wait
);
}
int
flags
=
0
;
if
(
wait_all
)
flags
|=
SELECT_ALL
;
if
(
alertable
)
flags
|=
SELECT_ALERTABLE
;
if
(
wait_msg
)
flags
|=
SELECT_MSG
;
if
(
timeout
!=
INFINITE32
)
flags
|=
SELECT_TIMEOUT
;
wait
->
signaled
=
CLIENT_Select
(
count
,
wait
->
server
,
flags
,
timeout
);
SYNC_FreeWaitStruct
(
wait
);
}
SYSTEM_UNLOCK
();
return
wait
->
signaled
;
}
...
...
scheduler/thread.c
View file @
55443878
...
...
@@ -25,20 +25,10 @@
THDB
*
pCurrentThread
;
#endif
static
BOOL32
THREAD_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
BOOL32
THREAD_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
THREAD_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
THREAD_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
);
static
void
THREAD_Destroy
(
K32OBJ
*
obj
);
const
K32OBJ_OPS
THREAD_Ops
=
{
THREAD_Signaled
,
/* signaled */
THREAD_Satisfied
,
/* satisfied */
THREAD_AddWait
,
/* add_wait */
THREAD_RemoveWait
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
THREAD_Destroy
/* destroy */
};
...
...
@@ -234,10 +224,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
0x10000
-
sizeof
(
STACK16FRAME
)
);
}
/* Allocate the event */
if
(
!
(
thdb
->
event
=
EVENT_Create
(
TRUE
,
FALSE
)))
goto
error
;
/* Create the thread socket */
if
(
CLIENT_NewThread
(
thdb
,
server_thandle
,
server_phandle
))
goto
error
;
...
...
@@ -274,56 +260,6 @@ error:
/***********************************************************************
* THREAD_Signaled
*/
static
BOOL32
THREAD_Signaled
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
THDB
*
thdb
=
(
THDB
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_THREAD
);
return
K32OBJ_OPS
(
thdb
->
event
)
->
signaled
(
thdb
->
event
,
thread_id
);
}
/***********************************************************************
* THREAD_Satisfied
*
* Wait on this object has been satisfied.
*/
static
BOOL32
THREAD_Satisfied
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
THDB
*
thdb
=
(
THDB
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_THREAD
);
return
K32OBJ_OPS
(
thdb
->
event
)
->
satisfied
(
thdb
->
event
,
thread_id
);
}
/***********************************************************************
* THREAD_AddWait
*
* Add thread to object wait queue.
*/
static
void
THREAD_AddWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
THDB
*
thdb
=
(
THDB
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_THREAD
);
return
K32OBJ_OPS
(
thdb
->
event
)
->
add_wait
(
thdb
->
event
,
thread_id
);
}
/***********************************************************************
* THREAD_RemoveWait
*
* Remove thread from object wait queue.
*/
static
void
THREAD_RemoveWait
(
K32OBJ
*
obj
,
DWORD
thread_id
)
{
THDB
*
thdb
=
(
THDB
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_THREAD
);
return
K32OBJ_OPS
(
thdb
->
event
)
->
remove_wait
(
thdb
->
event
,
thread_id
);
}
/***********************************************************************
* THREAD_Destroy
*/
static
void
THREAD_Destroy
(
K32OBJ
*
ptr
)
...
...
@@ -348,7 +284,6 @@ static void THREAD_Destroy( K32OBJ *ptr )
}
#endif
close
(
thdb
->
socket
);
K32OBJ_DecCount
(
thdb
->
event
);
SELECTOR_FreeBlock
(
thdb
->
teb_sel
,
1
);
if
(
thdb
->
teb
.
stack_sel
)
SELECTOR_FreeBlock
(
thdb
->
teb
.
stack_sel
,
1
);
HeapFree
(
SystemHeap
,
0
,
thdb
);
...
...
@@ -418,10 +353,6 @@ void WINAPI ExitThread(
SYSTEM_LOCK
();
thdb
->
exit_code
=
code
;
EVENT_Set
(
thdb
->
event
);
/* Abandon all owned mutexes */
while
(
thdb
->
mutex_list
)
MUTEX_Abandon
(
thdb
->
mutex_list
);
/* FIXME: should free the stack somehow */
#if 0
...
...
@@ -731,15 +662,13 @@ BOOL32 WINAPI TerminateThread(
HANDLE32
handle
,
/* [in] Handle to thread */
DWORD
exitcode
)
/* [in] Exit code for thread */
{
int
server_handle
;
BOOL32
ret
;
THDB
*
thread
;
if
(
!
(
thread
=
THREAD_GetPtr
(
handle
,
THREAD_TERMINATE
,
&
server_handle
)))
return
FALSE
;
ret
=
!
CLIENT_TerminateThread
(
server_handle
,
exitcode
);
K32OBJ_DecCount
(
&
thread
->
header
);
return
ret
;
struct
terminate_thread_request
req
;
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
handle
,
K32OBJ_THREAD
,
THREAD_TERMINATE
);
req
.
exit_code
=
exitcode
;
CLIENT_SendRequest
(
REQ_TERMINATE_THREAD
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
...
...
@@ -754,19 +683,11 @@ BOOL32 WINAPI GetExitCodeThread(
HANDLE32
hthread
,
/* [in] Handle to thread */
LPDWORD
exitcode
)
/* [out] Address to receive termination status */
{
THDB
*
thread
;
int
server_handle
;
if
(
!
(
thread
=
THREAD_GetPtr
(
hthread
,
THREAD_QUERY_INFORMATION
,
&
server_handle
)))
return
FALSE
;
if
(
server_handle
!=
-
1
)
{
struct
get_thread_info_reply
info
;
CLIENT_GetThreadInfo
(
server_handle
,
&
info
);
if
(
exitcode
)
*
exitcode
=
info
.
exit_code
;
}
else
if
(
exitcode
)
*
exitcode
=
thread
->
exit_code
;
K32OBJ_DecCount
(
&
thread
->
header
);
struct
get_thread_info_reply
info
;
int
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
hthread
,
K32OBJ_THREAD
,
THREAD_QUERY_INFORMATION
);
if
(
CLIENT_GetThreadInfo
(
handle
,
&
info
))
return
FALSE
;
if
(
exitcode
)
*
exitcode
=
info
.
exit_code
;
return
TRUE
;
}
...
...
win32/console.c
View file @
55443878
This diff is collapsed.
Click to expand it.
win32/device.c
View file @
55443878
...
...
@@ -32,14 +32,9 @@
#include "miscemu.h"
static
void
DEVICE_Destroy
(
K32OBJ
*
dev
);
const
K32OBJ_OPS
DEVICE_Ops
=
{
NULL
,
/* signaled */
NULL
,
/* satisfied */
NULL
,
/* add_wait */
NULL
,
/* remove_wait */
NULL
,
/* read */
NULL
,
/* write */
DEVICE_Destroy
/* destroy */
};
...
...
windows/queue.c
View file @
55443878
...
...
@@ -235,6 +235,8 @@ void QUEUE_Signal( HTASK16 hTask )
/* NOTE: This should really wake up *the* thread that owns
the queue. Since we dont't have thread-local message
queues yet, we wake up all waiting threads ... */
#if 0
/* FIXME: should be replaced by a server event */
SYSTEM_LOCK();
pdb = pTask->thdb->process;
entry = pdb? pdb->thread_list->next : NULL;
...
...
@@ -251,6 +253,7 @@ void QUEUE_Signal( HTASK16 hTask )
entry = entry->next;
}
SYSTEM_UNLOCK();
#endif
/* if ( !wakeup )*/
PostEvent
(
hTask
);
...
...
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