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
dd81ac50
Commit
dd81ac50
authored
Feb 24, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert async I/O queues to standard lists.
parent
91fc881d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
74 additions
and
88 deletions
+74
-88
fd.c
server/fd.c
+21
-31
file.c
server/file.c
+12
-14
file.h
server/file.h
+4
-4
serial.c
server/serial.c
+20
-18
sock.c
server/sock.c
+17
-21
No files found.
server/fd.c
View file @
dd81ac50
...
...
@@ -991,10 +991,23 @@ struct async
void
*
sb
;
struct
timeval
when
;
struct
timeout_user
*
timeout
;
struct
async
*
next
;
struct
async
**
head
;
struct
list
entry
;
};
/* notifies client thread of new status of its async request */
/* destroys the server side of it */
static
void
async_terminate
(
struct
async
*
async
,
int
status
)
{
thread_queue_apc
(
async
->
thread
,
NULL
,
async
->
apc
,
APC_ASYNC_IO
,
1
,
async
->
user
,
async
->
sb
,
(
void
*
)
status
);
if
(
async
->
timeout
)
remove_timeout_user
(
async
->
timeout
);
async
->
timeout
=
NULL
;
list_remove
(
&
async
->
entry
);
release_object
(
async
->
thread
);
free
(
async
);
}
/* cb for timeout on an async request */
static
void
async_callback
(
void
*
private
)
{
...
...
@@ -1006,12 +1019,10 @@ static void async_callback(void *private)
}
/* create an async on a given queue of a fd */
struct
async
*
create_async
(
struct
fd
*
fd
,
struct
thread
*
thread
,
int
timeout
,
struct
async
**
head
,
struct
async
*
create_async
(
struct
fd
*
fd
,
struct
thread
*
thread
,
int
timeout
,
struct
list
*
queue
,
void
*
io_apc
,
void
*
io_user
,
void
*
io_sb
)
{
struct
async
*
async
=
mem_alloc
(
sizeof
(
struct
async
)
);
struct
async
**
p
;
if
(
!
async
)
return
NULL
;
...
...
@@ -1020,11 +1031,8 @@ struct async *create_async(struct fd *fd, struct thread *thread,
async
->
apc
=
io_apc
;
async
->
user
=
io_user
;
async
->
sb
=
io_sb
;
async
->
head
=
head
;
async
->
next
=
NULL
;
for
(
p
=
head
;
*
p
;
p
=
&
(
*
p
)
->
next
);
*
p
=
async
;
list_add_tail
(
queue
,
&
async
->
entry
);
if
(
timeout
)
{
...
...
@@ -1037,29 +1045,11 @@ struct async *create_async(struct fd *fd, struct thread *thread,
return
async
;
}
/* notifies client thread of new status of its async request */
/* destroys the server side of it */
void
async_terminate
(
struct
async
*
async
,
int
status
)
/* terminate the async operation at the head of the queue */
void
async_terminate_head
(
struct
list
*
queue
,
int
status
)
{
struct
async
**
p
;
thread_queue_apc
(
async
->
thread
,
NULL
,
async
->
apc
,
APC_ASYNC_IO
,
1
,
async
->
user
,
async
->
sb
,
(
void
*
)
status
);
if
(
async
->
timeout
)
remove_timeout_user
(
async
->
timeout
);
async
->
timeout
=
NULL
;
for
(
p
=
async
->
head
;
*
p
;
p
=
&
(
*
p
)
->
next
)
{
if
(
*
p
==
async
)
{
*
p
=
async
->
next
;
break
;
}
}
release_object
(
async
->
thread
);
free
(
async
);
struct
list
*
ptr
=
list_head
(
queue
);
if
(
ptr
)
async_terminate
(
LIST_ENTRY
(
ptr
,
struct
async
,
entry
),
status
);
}
/****************************************************************/
...
...
server/file.c
View file @
dd81ac50
...
...
@@ -57,8 +57,8 @@ struct file
struct
fd
*
fd
;
/* file descriptor for this file */
unsigned
int
access
;
/* file access (GENERIC_READ/WRITE) */
unsigned
int
options
;
/* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
struct
async
*
read_q
;
struct
async
*
write_q
;
struct
list
read_q
;
struct
list
write_q
;
};
static
void
file_dump
(
struct
object
*
obj
,
int
verbose
);
...
...
@@ -160,10 +160,8 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int
file
->
access
=
access
;
file
->
options
=
options
;
if
(
is_overlapped
(
file
))
{
file
->
read_q
=
file
->
write_q
=
NULL
;
}
list_init
(
&
file
->
read_q
);
list_init
(
&
file
->
write_q
);
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
if
(
!
(
file
->
fd
=
alloc_fd
(
&
file_fd_ops
,
&
file
->
obj
))
||
...
...
@@ -237,14 +235,14 @@ static void file_poll_event( struct fd *fd, int event )
assert
(
file
->
obj
.
ops
==
&
file_ops
);
if
(
is_overlapped
(
file
))
{
if
(
file
->
read_q
&&
(
POLLIN
&
event
)
)
if
(
!
list_empty
(
&
file
->
read_q
)
&&
(
POLLIN
&
event
)
)
{
async_terminate
(
file
->
read_q
,
STATUS_ALERTED
);
async_terminate
_head
(
&
file
->
read_q
,
STATUS_ALERTED
);
return
;
}
if
(
file
->
write_q
&&
(
POLLOUT
&
event
)
)
if
(
!
list_empty
(
&
file
->
write_q
)
&&
(
POLLOUT
&
event
)
)
{
async_terminate
(
file
->
write_q
,
STATUS_ALERTED
);
async_terminate
_head
(
&
file
->
write_q
,
STATUS_ALERTED
);
return
;
}
}
...
...
@@ -271,7 +269,7 @@ static void file_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
int
type
,
int
count
)
{
struct
file
*
file
=
get_fd_user
(
fd
);
struct
async
**
head
;
struct
list
*
queue
;
int
events
;
assert
(
file
->
obj
.
ops
==
&
file_ops
);
...
...
@@ -285,17 +283,17 @@ static void file_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
switch
(
type
)
{
case
ASYNC_TYPE_READ
:
head
=
&
file
->
read_q
;
queue
=
&
file
->
read_q
;
break
;
case
ASYNC_TYPE_WRITE
:
head
=
&
file
->
write_q
;
queue
=
&
file
->
write_q
;
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
!
create_async
(
fd
,
current
,
0
,
head
,
apc
,
user
,
iosb
))
if
(
!
create_async
(
fd
,
current
,
0
,
queue
,
apc
,
user
,
iosb
))
return
;
/* Check if the new pending request can be served immediately */
...
...
server/file.h
View file @
dd81ac50
...
...
@@ -112,12 +112,12 @@ extern struct object *create_serial( struct fd *fd, unsigned int options );
/* async I/O functions */
extern
struct
async
*
create_async
(
struct
fd
*
fd
,
struct
thread
*
thread
,
int
timeout
,
struct
async
**
head
,
void
*
,
void
*
,
void
*
);
extern
void
async_terminate
(
struct
async
*
async
,
int
status
);
struct
list
*
queue
,
void
*
,
void
*
,
void
*
);
extern
void
async_terminate
_head
(
struct
list
*
queue
,
int
status
);
static
inline
void
async_terminate_queue
(
struct
async
**
head
,
int
status
)
static
inline
void
async_terminate_queue
(
struct
list
*
queue
,
int
status
)
{
while
(
*
head
)
async_terminate
(
*
head
,
status
);
while
(
!
list_empty
(
queue
))
async_terminate_head
(
queue
,
status
);
}
#endif
/* __WINE_SERVER_FILE_H */
server/serial.c
View file @
dd81ac50
...
...
@@ -83,9 +83,9 @@ struct serial
struct
termios
original
;
struct
async
*
read_q
;
struct
async
*
write_q
;
struct
async
*
wait_q
;
struct
list
read_q
;
struct
list
write_q
;
struct
list
wait_q
;
/* FIXME: add dcb, comm status, handler module, sharing */
};
...
...
@@ -145,7 +145,9 @@ struct object *create_serial( struct fd *fd, unsigned int options )
serial
->
writeconst
=
0
;
serial
->
eventmask
=
0
;
serial
->
commerror
=
0
;
serial
->
read_q
=
serial
->
write_q
=
serial
->
wait_q
=
NULL
;
list_init
(
&
serial
->
read_q
);
list_init
(
&
serial
->
write_q
);
list_init
(
&
serial
->
wait_q
);
if
(
!
(
serial
->
fd
=
create_anonymous_fd
(
&
serial_fd_ops
,
unix_fd
,
&
serial
->
obj
)))
{
release_object
(
serial
);
...
...
@@ -188,9 +190,9 @@ static int serial_get_poll_events( struct fd *fd )
int
events
=
0
;
assert
(
serial
->
obj
.
ops
==
&
serial_ops
);
if
(
serial
->
read_q
)
events
|=
POLLIN
;
if
(
serial
->
write_q
)
events
|=
POLLOUT
;
if
(
serial
->
wait_q
)
events
|=
POLLIN
;
if
(
!
list_empty
(
&
serial
->
read_q
)
)
events
|=
POLLIN
;
if
(
!
list_empty
(
&
serial
->
write_q
)
)
events
|=
POLLOUT
;
if
(
!
list_empty
(
&
serial
->
wait_q
)
)
events
|=
POLLIN
;
/* fprintf(stderr,"poll events are %04x\n",events); */
...
...
@@ -221,14 +223,14 @@ static void serial_poll_event(struct fd *fd, int event)
/* fprintf(stderr,"Poll event %02x\n",event); */
if
(
serial
->
read_q
&&
(
POLLIN
&
event
)
)
async_terminate
(
serial
->
read_q
,
STATUS_ALERTED
);
if
(
!
list_empty
(
&
serial
->
read_q
)
&&
(
POLLIN
&
event
)
)
async_terminate
_head
(
&
serial
->
read_q
,
STATUS_ALERTED
);
if
(
serial
->
write_q
&&
(
POLLOUT
&
event
)
)
async_terminate
(
serial
->
write_q
,
STATUS_ALERTED
);
if
(
!
list_empty
(
&
serial
->
write_q
)
&&
(
POLLOUT
&
event
)
)
async_terminate
_head
(
&
serial
->
write_q
,
STATUS_ALERTED
);
if
(
serial
->
wait_q
&&
(
POLLIN
&
event
)
)
async_terminate
(
serial
->
wait_q
,
STATUS_ALERTED
);
if
(
!
list_empty
(
&
serial
->
wait_q
)
&&
(
POLLIN
&
event
)
)
async_terminate
_head
(
&
serial
->
wait_q
,
STATUS_ALERTED
);
set_fd_events
(
fd
,
serial_get_poll_events
(
fd
)
);
}
...
...
@@ -237,7 +239,7 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb
int
type
,
int
count
)
{
struct
serial
*
serial
=
get_fd_user
(
fd
);
struct
async
**
head
;
struct
list
*
queue
;
int
timeout
;
int
events
;
...
...
@@ -246,15 +248,15 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb
switch
(
type
)
{
case
ASYNC_TYPE_READ
:
head
=
&
serial
->
read_q
;
queue
=
&
serial
->
read_q
;
timeout
=
serial
->
readconst
+
serial
->
readmult
*
count
;
break
;
case
ASYNC_TYPE_WAIT
:
head
=
&
serial
->
wait_q
;
queue
=
&
serial
->
wait_q
;
timeout
=
0
;
break
;
case
ASYNC_TYPE_WRITE
:
head
=
&
serial
->
write_q
;
queue
=
&
serial
->
write_q
;
timeout
=
serial
->
writeconst
+
serial
->
writemult
*
count
;
break
;
default:
...
...
@@ -262,7 +264,7 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb
return
;
}
if
(
!
create_async
(
fd
,
current
,
timeout
,
head
,
apc
,
user
,
iosb
))
if
(
!
create_async
(
fd
,
current
,
timeout
,
queue
,
apc
,
user
,
iosb
))
return
;
/* Check if the new pending request can be served immediately */
...
...
server/sock.c
View file @
dd81ac50
...
...
@@ -81,8 +81,8 @@ struct sock
obj_handle_t
wparam
;
/* message wparam (socket handle) */
int
errors
[
FD_MAX_EVENTS
];
/* event errors */
struct
sock
*
deferred
;
/* socket that waits for a deferred accept */
struct
async
*
read_q
;
/* Q
ueue for asynchronous reads */
struct
async
*
write_q
;
/* Q
ueue for asynchronous writes */
struct
list
read_q
;
/* q
ueue for asynchronous reads */
struct
list
write_q
;
/* q
ueue for asynchronous writes */
};
static
void
sock_dump
(
struct
object
*
obj
,
int
verbose
);
...
...
@@ -237,16 +237,16 @@ static void sock_wake_up( struct sock *sock, int pollev )
if
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
)
{
if
(
pollev
&
(
POLLIN
|
POLLPRI
)
&&
sock
->
read_q
)
if
(
pollev
&
(
POLLIN
|
POLLPRI
)
&&
!
list_empty
(
&
sock
->
read_q
)
)
{
if
(
debug_level
)
fprintf
(
stderr
,
"activating read queue for socket %p
\n
"
,
sock
);
async_terminate
(
sock
->
read_q
,
STATUS_ALERTED
);
async_terminate
_head
(
&
sock
->
read_q
,
STATUS_ALERTED
);
async_active
=
1
;
}
if
(
pollev
&
POLLOUT
&&
sock
->
write_q
)
if
(
pollev
&
POLLOUT
&&
!
list_empty
(
&
sock
->
write_q
)
)
{
if
(
debug_level
)
fprintf
(
stderr
,
"activating write queue for socket %p
\n
"
,
sock
);
async_terminate
(
sock
->
write_q
,
STATUS_ALERTED
);
async_terminate
_head
(
&
sock
->
write_q
,
STATUS_ALERTED
);
async_active
=
1
;
}
}
...
...
@@ -466,9 +466,9 @@ static int sock_get_poll_events( struct fd *fd )
/* listening, wait for readable */
return
(
sock
->
hmask
&
FD_ACCEPT
)
?
0
:
POLLIN
;
if
(
mask
&
(
FD_READ
)
||
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
&&
sock
->
read_q
))
if
(
mask
&
(
FD_READ
)
||
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
&&
!
list_empty
(
&
sock
->
read_q
)
))
ev
|=
POLLIN
|
POLLPRI
;
if
(
mask
&
FD_WRITE
||
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
&&
sock
->
write_q
))
if
(
mask
&
FD_WRITE
||
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
&&
!
list_empty
(
&
sock
->
write_q
)
))
ev
|=
POLLOUT
;
/* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */
if
(
sock
->
type
==
SOCK_STREAM
&&
(
sock
->
mask
&
~
sock
->
hmask
&
FD_CLOSE
)
)
...
...
@@ -496,9 +496,9 @@ static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
int
type
,
int
count
)
{
struct
sock
*
sock
=
get_fd_user
(
fd
);
struct
async
**
head
;
struct
list
*
queue
;
int
pollev
;
assert
(
sock
->
obj
.
ops
==
&
sock_ops
);
if
(
!
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
)
)
...
...
@@ -510,11 +510,11 @@ static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
switch
(
type
)
{
case
ASYNC_TYPE_READ
:
head
=
&
sock
->
read_q
;
queue
=
&
sock
->
read_q
;
sock
->
hmask
&=
~
FD_CLOSE
;
break
;
case
ASYNC_TYPE_WRITE
:
head
=
&
sock
->
write_q
;
queue
=
&
sock
->
write_q
;
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
...
...
@@ -528,7 +528,7 @@ static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
}
else
{
if
(
!
create_async
(
fd
,
current
,
0
,
head
,
apc
,
user
,
iosb
))
if
(
!
create_async
(
fd
,
current
,
0
,
queue
,
apc
,
user
,
iosb
))
return
;
}
...
...
@@ -608,10 +608,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
release_object
(
sock
);
return
NULL
;
}
if
(
sock
->
flags
&
WSA_FLAG_OVERLAPPED
)
{
sock
->
read_q
=
sock
->
write_q
=
NULL
;
}
list_init
(
&
sock
->
read_q
);
list_init
(
&
sock
->
write_q
);
sock_reselect
(
sock
);
clear_error
();
return
&
sock
->
obj
;
...
...
@@ -682,10 +680,8 @@ static struct sock *accept_socket( obj_handle_t handle )
release_object
(
sock
);
return
NULL
;
}
if
(
acceptsock
->
flags
&
WSA_FLAG_OVERLAPPED
)
{
acceptsock
->
read_q
=
acceptsock
->
write_q
=
NULL
;
}
list_init
(
&
acceptsock
->
read_q
);
list_init
(
&
acceptsock
->
write_q
);
}
clear_error
();
sock
->
pmask
&=
~
FD_ACCEPT
;
...
...
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