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
ad7538bf
Commit
ad7538bf
authored
Dec 14, 1998
by
Marcus Meissner
Committed by
Alexandre Julliard
Dec 14, 1998
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made async IO (SIGIO) stuff from WINSOCK generic useable.
Added async IO support to FILE and CONSOLE objects.
parent
0875d6e9
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
274 additions
and
79 deletions
+274
-79
Makefile.in
files/Makefile.in
+1
-0
async.c
files/async.c
+186
-0
file.c
files/file.c
+21
-6
async.h
include/async.h
+6
-0
file.h
include/file.h
+3
-0
signal.c
loader/signal.c
+3
-1
winsock_dns.c
misc/winsock_dns.c
+22
-64
console.c
win32/console.c
+32
-8
No files found.
files/Makefile.in
View file @
ad7538bf
...
...
@@ -8,6 +8,7 @@ VPATH = @srcdir@
MODULE
=
files
C_SRCS
=
\
async.c
\
change.c
\
directory.c
\
dos_fs.c
\
...
...
files/async.c
0 → 100644
View file @
ad7538bf
/*
* Generic async UNIX file IO handling
*
* Copyright 1996,1997 Alex Korobka
* Copyright 1998 Marcus Meissner
*/
/*
* This file handles asynchronous signaling for UNIX filedescriptors.
* The passed handler gets called when input arrived for the filedescriptor.
*
* This is done either by the kernel or (in the WINSOCK case) by the pipe
* handler, since pipes do not support asynchronous signaling.
* (Not all possible filedescriptors support async IO. Generic files do not
* for instance, sockets do, ptys don't.)
*
* To make this a bit better, we would need an additional thread doing select()
*/
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef __svr4__
# include <sys/file.h>
#endif
#include "xmalloc.h"
#include "wintypes.h"
#include "miscemu.h"
#include "selectors.h"
#include "sig_context.h"
#include "async.h"
#include "debug.h"
typedef
struct
_async_fd
{
int
unixfd
;
void
(
*
handler
)(
int
fd
,
void
*
private
);
void
*
private
;
}
ASYNC_FD
;
static
ASYNC_FD
*
asyncfds
=
NULL
;
static
int
nrofasyncfds
=
0
;
/***************************************************************************
* ASYNC_sigio [internal]
*
* Signal handler for asynchronous IO.
*
* Note: This handler and the function it calls may not block. Neither they
* are allowed to use blocking IO (write/read). No memory management.
* No possible blocking synchronization of any kind.
*/
HANDLER_DEF
(
ASYNC_sigio
)
{
struct
timeval
timeout
;
fd_set
rset
,
wset
;
int
i
,
maxfd
=
0
;
HANDLER_INIT
();
if
(
!
nrofasyncfds
)
return
;
FD_ZERO
(
&
rset
);
FD_ZERO
(
&
wset
);
for
(
i
=
nrofasyncfds
;
i
--
;)
{
if
(
asyncfds
[
i
].
unixfd
==
-
1
)
continue
;
FD_SET
(
asyncfds
[
i
].
unixfd
,
&
rset
);
FD_SET
(
asyncfds
[
i
].
unixfd
,
&
wset
);
if
(
maxfd
<
asyncfds
[
i
].
unixfd
)
maxfd
=
asyncfds
[
i
].
unixfd
;
}
/* select() with timeout values set to 0 is nonblocking. */
memset
(
&
timeout
,
0
,
sizeof
(
timeout
));
if
(
select
(
maxfd
+
1
,
&
rset
,
&
wset
,
NULL
,
&
timeout
)
<=
0
)
return
;
/* Can't be. hmm */
for
(
i
=
nrofasyncfds
;
i
--
;)
if
(
(
FD_ISSET
(
asyncfds
[
i
].
unixfd
,
&
rset
))
||
(
FD_ISSET
(
asyncfds
[
i
].
unixfd
,
&
wset
))
)
asyncfds
[
i
].
handler
(
asyncfds
[
i
].
unixfd
,
asyncfds
[
i
].
private
);
}
/***************************************************************************
* ASYNC_MakeFDAsync [internal]
*
* Makes the passed filedescriptor async (or not) depending on flag.
*/
static
BOOL32
ASYNC_MakeFDAsync
(
int
unixfd
,
int
async
)
{
int
flags
;
#if !defined(FASYNC) && defined(FIOASYNC)
#define FASYNC FIOASYNC
#endif
#ifdef F_SETOWN
if
(
-
1
==
fcntl
(
unixfd
,
F_SETOWN
,
getpid
()))
perror
(
"fcntl F_SETOWN <pid>"
);
#endif
#ifdef FASYNC
if
(
-
1
==
fcntl
(
unixfd
,
F_GETFL
,
&
flags
))
{
perror
(
"fcntl F_GETFL"
);
return
FALSE
;
}
if
(
async
)
flags
|=
FASYNC
;
else
flags
&=~
FASYNC
;
if
(
-
1
==
fcntl
(
unixfd
,
F_SETFL
,
&
flags
))
{
perror
(
"fcntl F_SETFL FASYNC"
);
return
FALSE
;
}
return
TRUE
;
#else
return
FALSE
;
#endif
}
/***************************************************************************
* ASYNC_RegisterFD [internal]
*
* Register a UNIX filedescriptor with handler and private data pointer.
* this function is _NOT_ safe to be called from a signal handler.
*
* Additional Constraint: The handler passed to this function _MUST_ adhere
* to the same signalsafeness as ASYNC_sigio itself. (nonblocking, no thread/
* signal unsafe operations, no blocking synchronization)
*/
void
ASYNC_RegisterFD
(
int
unixfd
,
void
(
*
handler
)(
int
fd
,
void
*
private
),
void
*
private
)
{
int
i
;
SIGNAL_MaskAsyncEvents
(
TRUE
);
for
(
i
=
0
;
i
<
nrofasyncfds
;
i
++
)
{
if
(
asyncfds
[
i
].
unixfd
==
unixfd
)
{
/* Might be a leftover entry. Make fd async anyway... */
if
(
asyncfds
[
i
].
handler
==
handler
)
{
ASYNC_MakeFDAsync
(
unixfd
,
1
);
SIGNAL_MaskAsyncEvents
(
FALSE
);
return
;
}
}
}
for
(
i
=
0
;
i
<
nrofasyncfds
;
i
++
)
if
(
asyncfds
[
i
].
unixfd
==
-
1
)
break
;
if
(
i
==
nrofasyncfds
)
{
if
(
nrofasyncfds
)
asyncfds
=
(
ASYNC_FD
*
)
xrealloc
(
asyncfds
,
sizeof
(
ASYNC_FD
)
*
(
nrofasyncfds
+
1
));
else
asyncfds
=
(
ASYNC_FD
*
)
xmalloc
(
sizeof
(
ASYNC_FD
)
*
1
);
nrofasyncfds
++
;
}
asyncfds
[
i
].
unixfd
=
unixfd
;
asyncfds
[
i
].
handler
=
handler
;
asyncfds
[
i
].
private
=
private
;
ASYNC_MakeFDAsync
(
unixfd
,
1
);
SIGNAL_MaskAsyncEvents
(
FALSE
);
}
/***************************************************************************
* ASYNC_UnregisterFD [internal]
*
* Unregister a UNIX filedescriptor with handler. This function is basically
* signal safe, but try to not call it in the signal handler anyway.
*/
void
ASYNC_UnregisterFD
(
int
unixfd
,
void
(
*
handler
)(
int
fd
,
void
*
private
))
{
int
i
;
for
(
i
=
nrofasyncfds
;
i
--
;)
if
((
asyncfds
[
i
].
unixfd
==
unixfd
)
||
(
asyncfds
[
i
].
handler
==
handler
))
break
;
if
(
i
==
nrofasyncfds
)
return
;
asyncfds
[
i
].
unixfd
=
-
1
;
asyncfds
[
i
].
handler
=
NULL
;
asyncfds
[
i
].
private
=
NULL
;
return
;
}
files/file.c
View file @
ad7538bf
...
...
@@ -35,6 +35,7 @@
#include "ldt.h"
#include "process.h"
#include "task.h"
#include "async.h"
#include "debug.h"
#if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
...
...
@@ -97,6 +98,7 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file )
(
*
file
)
->
type
=
FILE_TYPE_DISK
;
(
*
file
)
->
pos
=
0
;
(
*
file
)
->
mode
=
0
;
(
*
file
)
->
wait_queue
=
NULL
;
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
&
(
*
file
)
->
header
,
FILE_ALL_ACCESS
|
GENERIC_READ
|
...
...
@@ -106,6 +108,16 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file )
return
handle
;
}
/***********************************************************************
* FILE_async_handler [internal]
*/
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
;
...
...
@@ -127,20 +139,23 @@ static BOOL32 FILE_Signaled(K32OBJ *ptr, DWORD thread_id)
static
void
FILE_AddWait
(
K32OBJ
*
ptr
,
DWORD
thread_id
)
{
TRACE
(
file
,
"(),stub
\n
"
);
return
;
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
)
{
TRACE
(
file
,
"(),stub
\n
"
);
return
;
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
)
{
TRACE
(
file
,
"(),stub
\n
"
);
return
TRUE
;
return
FALSE
;
/* not abandoned. Hmm? */
}
/* FIXME: lpOverlapped is ignored */
...
...
include/async.h
0 → 100644
View file @
ad7538bf
#ifndef __WINE_ASYNC_H
#define __WINE_ASYNC_H
extern
void
ASYNC_RegisterFD
(
int
unixfd
,
void
(
*
handler
)(
int
fd
,
void
*
private
),
void
*
private
);
extern
void
ASYNC_UnregisterFD
(
int
unixfd
,
void
(
*
handler
)(
int
fd
,
void
*
private
));
#endif
include/file.h
View file @
ad7538bf
...
...
@@ -10,6 +10,7 @@
#include <time.h>
#include "windows.h"
#include "k32obj.h"
#include "thread.h"
#define MAX_PATHNAME_LEN 1024
...
...
@@ -22,6 +23,8 @@ typedef struct
char
*
unix_name
;
DWORD
type
;
/* Type for win32 apps */
DWORD
pos
;
/* workaround to emulate weird DOS error handling */
THREAD_QUEUE
wait_queue
;
}
FILE_OBJECT
;
/* Definition of a full DOS file name */
...
...
loader/signal.c
View file @
ad7538bf
...
...
@@ -148,6 +148,7 @@ void SIGNAL_SetHandler( int sig, void (*func)(), int flags )
extern
void
stop_wait
(
int
a
);
extern
void
WINSOCK_sigio
(
int
a
);
extern
void
ASYNC_sigio
(
int
a
);
/**********************************************************************
...
...
@@ -178,7 +179,8 @@ BOOL32 SIGNAL_Init(void)
#endif
#ifdef SIGIO
sigaddset
(
&
async_signal_set
,
SIGIO
);
SIGNAL_SetHandler
(
SIGIO
,
(
void
(
*
)())
WINSOCK_sigio
,
0
);
/* SIGNAL_SetHandler( SIGIO, (void (*)())WINSOCK_sigio, 0); */
SIGNAL_SetHandler
(
SIGIO
,
(
void
(
*
)())
ASYNC_sigio
,
0
);
#endif
sigaddset
(
&
async_signal_set
,
SIGALRM
);
...
...
misc/winsock_dns.c
View file @
ad7538bf
...
...
@@ -11,6 +11,7 @@
#include "config.h"
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
...
...
@@ -38,14 +39,11 @@
#include "heap.h"
#include "ldt.h"
#include "message.h"
#include "selectors.h"
#include "miscemu.h"
#include "
sig_context
.h"
#include "
async
.h"
#include "debug.h"
#ifndef FASYNC
#define FASYNC FIOASYNC
#endif
static
void
WINSOCK_async_handler
(
int
unixfd
,
void
*
private
);
/* async DNS op control struct */
typedef
struct
...
...
@@ -67,9 +65,6 @@ extern void* __ws_memalloc( int size );
extern
void
__ws_memfree
(
void
*
ptr
);
/* NOTE: ws_async_op list is traversed inside the SIGIO handler! */
static
int
__async_io_max_fd
=
0
;
static
fd_set
__async_io_fdset
;
static
ws_async_op
*
__async_op_list
=
NULL
;
static
void
fixup_wshe
(
struct
ws_hostent
*
p_wshe
,
void
*
base
);
...
...
@@ -78,20 +73,6 @@ static void fixup_wsse(struct ws_servent* p_wsse, void* base);
/* ----------------------------------- async/non-blocking I/O */
int
WINSOCK_async_io
(
int
fd
,
int
async
)
{
int
fd_flags
;
#ifndef __EMX__
fcntl
(
fd
,
F_SETOWN
,
getpid
());
#endif
fd_flags
=
fcntl
(
fd
,
F_GETFL
,
0
);
if
(
fcntl
(
fd
,
F_SETFL
,
(
async
)
?
fd_flags
|
FASYNC
:
fd_flags
&
~
FASYNC
)
!=
-
1
)
return
0
;
return
-
1
;
}
int
WINSOCK_unblock_io
(
int
fd
,
int
noblock
)
{
int
fd_flags
;
...
...
@@ -191,14 +172,12 @@ void WINSOCK_link_async_op(ws_async_op* p_aop)
p
=
p
->
next
;
}
}
else
FD_ZERO
(
&
__async_io_fdset
);
p_aop
->
next
=
__async_op_list
;
__async_op_list
=
p_aop
;
SIGNAL_MaskAsyncEvents
(
FALSE
);
FD_SET
(
p_aop
->
fd
[
0
],
&
__async_io_fdset
);
if
(
p_aop
->
fd
[
0
]
>
__async_io_max_fd
)
__async_io_max_fd
=
p_aop
->
fd
[
0
];
ASYNC_RegisterFD
(
p_aop
->
fd
[
0
],
WINSOCK_async_handler
,
p_aop
);
}
void
WINSOCK_unlink_async_op
(
ws_async_op
*
p_aop
)
...
...
@@ -210,9 +189,7 @@ void WINSOCK_unlink_async_op(ws_async_op* p_aop)
p_aop
->
prev
->
next
=
p_aop
->
next
;
if
(
p_aop
->
next
)
p_aop
->
next
->
prev
=
p_aop
->
prev
;
FD_CLR
(
p_aop
->
fd
[
0
],
&
__async_io_fdset
);
if
(
p_aop
->
fd
[
0
]
==
__async_io_max_fd
)
__async_io_max_fd
--
;
ASYNC_UnregisterFD
(
p_aop
->
fd
[
0
],
WINSOCK_async_handler
);
}
/* ----------------------------------- SIGIO handler -
...
...
@@ -223,42 +200,23 @@ void WINSOCK_unlink_async_op(ws_async_op* p_aop)
* Note: pipe-based handlers must raise explicit SIGIO with kill(2).
*/
HANDLER_DEF
(
WINSOCK_sigio
)
static
void
WINSOCK_async_handler
(
int
unixfd
,
void
*
private
)
{
struct
timeval
timeout
;
fd_set
check_set
;
ws_async_op
*
p_aop
;
HANDLER_INIT
();
check_set
=
__async_io_fdset
;
memset
(
&
timeout
,
0
,
sizeof
(
timeout
));
while
(
select
(
__async_io_max_fd
+
1
,
&
check_set
,
NULL
,
NULL
,
&
timeout
)
>
0
)
{
for
(
p_aop
=
__async_op_list
;
p_aop
;
p_aop
=
p_aop
->
next
)
if
(
FD_ISSET
(
p_aop
->
fd
[
0
],
&
check_set
)
)
if
(
p_aop
->
aop_control
(
p_aop
,
AOP_IO
)
==
AOP_CONTROL_REMOVE
)
{
/* NOTE: memory management is signal-unsafe, therefore
* we can only set a flag to remove this p_aop later on.
*/
p_aop
->
flags
=
WSMSG_DEAD_AOP
;
close
(
p_aop
->
fd
[
0
]);
FD_CLR
(
p_aop
->
fd
[
0
],
&
__async_io_fdset
);
if
(
p_aop
->
fd
[
0
]
==
__async_io_max_fd
)
__async_io_max_fd
=
p_aop
->
fd
[
0
];
if
(
p_aop
->
pid
)
{
kill
(
p_aop
->
pid
,
SIGKILL
);
waitpid
(
p_aop
->
pid
,
NULL
,
WNOHANG
);
p_aop
->
pid
=
0
;
}
}
check_set
=
__async_io_fdset
;
ws_async_op
*
p_aop
=
(
ws_async_op
*
)
private
;
if
(
p_aop
->
aop_control
(
p_aop
,
AOP_IO
)
==
AOP_CONTROL_REMOVE
)
{
/* NOTE: memory management is signal-unsafe, therefore
* we can only set a flag to remove this p_aop later on.
*/
p_aop
->
flags
=
WSMSG_DEAD_AOP
;
close
(
p_aop
->
fd
[
0
]);
if
(
p_aop
->
pid
)
{
kill
(
p_aop
->
pid
,
SIGKILL
);
waitpid
(
p_aop
->
pid
,
NULL
,
WNOHANG
);
p_aop
->
pid
=
0
;
}
}
}
...
...
win32/console.c
View file @
ad7538bf
...
...
@@ -32,8 +32,11 @@
#include <sys/errno.h>
#include <signal.h>
#include <assert.h>
#include "windows.h"
#include "k32obj.h"
#include "thread.h"
#include "async.h"
#include "file.h"
#include "process.h"
#include "winerror.h"
...
...
@@ -53,6 +56,7 @@ typedef struct _CONSOLE {
LPSTR
title
;
/* title of console */
INPUT_RECORD
*
irs
;
/* buffered input records */
int
nrofirs
;
/* nr of buffered input records */
THREAD_QUEUE
wait_queue
;
}
CONSOLE
;
static
void
CONSOLE_AddWait
(
K32OBJ
*
ptr
,
DWORD
thread_id
);
...
...
@@ -378,6 +382,16 @@ CONSOLE_drain_input(CONSOLE *console,int n) {
}
/***********************************************************************
* CONSOLE_async_handler [internal]
*/
static
void
CONSOLE_async_handler
(
int
unixfd
,
void
*
private
)
{
CONSOLE
*
console
=
(
CONSOLE
*
)
private
;
SYNC_WakeUp
(
&
console
->
wait_queue
,
INFINITE32
);
}
/***********************************************************************
* CONSOLE_Signaled [internal]
*
* Checks if we can read something. (Hmm, what about writing ?)
...
...
@@ -389,7 +403,10 @@ CONSOLE_Signaled(K32OBJ *ptr,DWORD tid) {
if
(
ptr
->
type
!=
K32OBJ_CONSOLE
)
return
FALSE
;
CONSOLE_get_input
(
console
);
return
console
->
nrofirs
!=
0
;
if
(
console
->
nrofirs
!=
0
)
return
TRUE
;
/* addref console */
return
FALSE
;
}
/***********************************************************************
...
...
@@ -399,19 +416,26 @@ CONSOLE_Signaled(K32OBJ *ptr,DWORD tid) {
*/
static
void
CONSOLE_AddWait
(
K32OBJ
*
ptr
,
DWORD
thread_id
)
{
WARN
(
console
,
"(),stub. Expect hang.
\n
"
);
return
;
CONSOLE
*
console
=
(
CONSOLE
*
)
ptr
;
/* register our unix filedescriptors for async IO */
if
(
!
console
->
wait_queue
)
ASYNC_RegisterFD
(
console
->
infd
,
CONSOLE_async_handler
,
console
);
THREAD_AddQueue
(
&
console
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
}
/***********************************************************************
* CONSOLE_
Add
Wait [internal]
* CONSOLE_
Remove
Wait [internal]
*
* Remove thread from our waitqueue.
*/
static
void
CONSOLE_RemoveWait
(
K32OBJ
*
ptr
,
DWORD
thread_id
)
{
TRACE
(
console
,
"(),stub
\n
"
);
return
;
CONSOLE
*
console
=
(
CONSOLE
*
)
ptr
;
THREAD_RemoveQueue
(
&
console
->
wait_queue
,
THREAD_ID_TO_THDB
(
thread_id
)
);
if
(
!
console
->
wait_queue
)
ASYNC_UnregisterFD
(
console
->
infd
,
CONSOLE_async_handler
);
}
/***********************************************************************
...
...
@@ -421,8 +445,7 @@ static void CONSOLE_RemoveWait(K32OBJ *ptr, DWORD thread_id)
*/
static
BOOL32
CONSOLE_Satisfied
(
K32OBJ
*
ptr
,
DWORD
thread_id
)
{
TRACE
(
console
,
"(),stub
\n
"
);
return
TRUE
;
return
FALSE
;
}
...
...
@@ -784,6 +807,7 @@ BOOL32 WINAPI AllocConsole(VOID)
console
->
pid
=
-
1
;
console
->
title
=
NULL
;
console
->
nrofirs
=
0
;
console
->
wait_queue
=
NULL
;
console
->
irs
=
HeapAlloc
(
GetProcessHeap
(),
0
,
1
);;
console
->
mode
=
ENABLE_PROCESSED_INPUT
|
ENABLE_LINE_INPUT
...
...
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