Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
54ba2720
Commit
54ba2720
authored
Apr 24, 2002
by
Martin Wilck
Committed by
Alexandre Julliard
Apr 24, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add more flexibility to the queue_async server call by moving most
functionality into the object's queue_async method.
parent
14a913c2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
61 deletions
+62
-61
async.c
server/async.c
+22
-32
file.c
server/file.c
+21
-7
object.h
server/object.h
+2
-2
serial.c
server/serial.c
+17
-20
No files found.
server/async.c
View file @
54ba2720
...
...
@@ -150,42 +150,32 @@ void async_add_timeout(struct async *async, int timeout)
DECL_HANDLER
(
register_async
)
{
struct
object
*
obj
;
struct
object
*
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
NULL
)
;
if
(
!
(
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
NULL
))
)
return
;
if
(
obj
->
ops
->
queue_async
)
if
(
!
(
obj
)
||
!
obj
->
ops
->
queue_async
)
{
struct
async_queue
*
q
=
obj
->
ops
->
queue_async
(
obj
,
NULL
,
req
->
type
,
0
);
struct
async
*
async
;
async
=
find_async
(
q
,
current
,
req
->
overlapped
);
if
(
req
->
status
==
STATUS_PENDING
)
{
if
(
!
async
)
async
=
create_async
(
obj
,
current
,
req
->
overlapped
);
if
(
async
)
{
async
->
status
=
req
->
status
;
if
(
!
obj
->
ops
->
queue_async
(
obj
,
async
,
req
->
type
,
req
->
count
))
destroy_async
(
async
);
}
}
else
{
if
(
async
)
destroy_async
(
async
);
else
set_error
(
STATUS_INVALID_PARAMETER
);
}
set_select_events
(
obj
,
obj
->
ops
->
get_poll_events
(
obj
));
}
else
set_error
(
STATUS_INVALID_HANDLE
);
return
;
}
/*
* The queue_async method must do the following:
*
* 1. Get the async_queue for the request of given type.
* 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
* 3. If status is STATUS_PENDING:
* a) If no async request found in step 2 (new request): call create_async() to initialize one.
* b) Set request's status to STATUS_PENDING.
* c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
* Otherwise:
* If the async request was found in step 2, destroy it by calling destroy_async().
* 4. Carry out any operations necessary to adjust the object's poll events
* Usually: set_elect_events (obj, obj->ops->get_poll_events()).
*
* See also the implementations in file.c, serial.c, and sock.c.
*/
obj
->
ops
->
queue_async
(
obj
,
req
->
overlapped
,
req
->
status
,
req
->
type
,
req
->
count
);
release_object
(
obj
);
}
server/file.c
View file @
54ba2720
...
...
@@ -69,7 +69,7 @@ static int file_get_fd( struct object *obj );
static
int
file_flush
(
struct
object
*
obj
);
static
int
file_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
,
int
*
flags
);
static
void
file_destroy
(
struct
object
*
obj
);
static
struct
async_queue
*
file_queue_async
(
struct
object
*
obj
,
struct
async
*
async
,
int
type
,
int
count
);
static
void
file_queue_async
(
struct
object
*
obj
,
void
*
ptr
,
unsigned
int
status
,
int
type
,
int
count
);
static
const
struct
object_ops
file_ops
=
{
...
...
@@ -358,9 +358,10 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply,
return
FD_TYPE_DEFAULT
;
}
static
struct
async_queue
*
file_queue_async
(
struct
object
*
obj
,
struct
async
*
async
,
int
type
,
int
count
)
static
void
file_queue_async
(
struct
object
*
obj
,
void
*
ptr
,
unsigned
int
status
,
int
type
,
int
count
)
{
struct
file
*
file
=
(
struct
file
*
)
obj
;
struct
async
*
async
;
struct
async_queue
*
q
;
assert
(
obj
->
ops
==
&
file_ops
);
...
...
@@ -368,7 +369,7 @@ static struct async_queue *file_queue_async(struct object *obj, struct async *as
if
(
!
(
file
->
flags
&
FILE_FLAG_OVERLAPPED
)
)
{
set_error
(
STATUS_INVALID_HANDLE
);
return
NULL
;
return
;
}
switch
(
type
)
...
...
@@ -381,13 +382,26 @@ static struct async_queue *file_queue_async(struct object *obj, struct async *as
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
NULL
;
return
;
}
if
(
async
&&
!
async
->
q
)
async_insert
(
q
,
async
);
async
=
find_async
(
q
,
current
,
ptr
);
if
(
status
==
STATUS_PENDING
)
{
if
(
!
async
)
async
=
create_async
(
obj
,
current
,
ptr
);
if
(
!
async
)
return
;
async
->
status
=
STATUS_PENDING
;
if
(
!
async
->
q
)
async_insert
(
q
,
async
);
}
else
if
(
async
)
destroy_async
(
async
);
else
set_error
(
STATUS_INVALID_PARAMETER
);
return
q
;
set_select_events
(
obj
,
file_get_poll_events
(
obj
))
;
}
static
void
file_destroy
(
struct
object
*
obj
)
...
...
server/object.h
View file @
54ba2720
...
...
@@ -63,8 +63,8 @@ struct object_ops
int
(
*
flush
)(
struct
object
*
);
/* get file information */
int
(
*
get_file_info
)(
struct
object
*
,
struct
get_file_info_reply
*
,
int
*
flags
);
/* queue an async operation */
struct
async_queue
*
(
*
queue_async
)(
struct
object
*
,
struct
async
*
async
,
int
type
,
int
count
);
/* queue an async operation
- see register_async handler in async.c
*/
void
(
*
queue_async
)(
struct
object
*
,
void
*
ptr
,
unsigned
int
status
,
int
type
,
int
count
);
/* destroy on refcount == 0 */
void
(
*
destroy
)(
struct
object
*
);
};
...
...
server/serial.c
View file @
54ba2720
...
...
@@ -51,7 +51,7 @@ static void serial_dump( struct object *obj, int verbose );
static
int
serial_get_fd
(
struct
object
*
obj
);
static
int
serial_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
,
int
*
flags
);
static
int
serial_get_poll_events
(
struct
object
*
obj
);
static
struct
async_queue
*
serial_queue_async
(
struct
object
*
obj
,
struct
async
*
async
,
int
type
,
int
count
);
static
void
serial_queue_async
(
struct
object
*
obj
,
void
*
ptr
,
unsigned
int
status
,
int
type
,
int
count
);
static
void
destroy_serial
(
struct
object
*
obj
);
static
void
serial_poll_event
(
struct
object
*
obj
,
int
event
);
...
...
@@ -250,24 +250,11 @@ static void serial_poll_event(struct object *obj, int event)
set_select_events
(
obj
,
obj
->
ops
->
get_poll_events
(
obj
));
}
/*
* This function is an abuse of overloading that deserves some explanation.
*
* It has three purposes:
*
* 1. get the queue for a type of async operation
* 2. requeue an async operation
* 3. queue a new async operation
*
* It is overloaded so that these three functions only take one function pointer
* in the object operations list.
*
* In all cases, it returns the async queue.
*/
static
struct
async_queue
*
serial_queue_async
(
struct
object
*
obj
,
struct
async
*
async
,
int
type
,
int
count
)
static
void
serial_queue_async
(
struct
object
*
obj
,
void
*
ptr
,
unsigned
int
status
,
int
type
,
int
count
)
{
struct
serial
*
serial
=
(
struct
serial
*
)
obj
;
struct
async_queue
*
q
;
struct
async
*
async
;
int
timeout
;
assert
(
obj
->
ops
==
&
serial_ops
);
...
...
@@ -288,19 +275,29 @@ static struct async_queue *serial_queue_async(struct object *obj, struct async *
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
NULL
;
return
;
}
if
(
async
)
async
=
find_async
(
q
,
current
,
ptr
);
if
(
status
==
STATUS_PENDING
)
{
if
(
!
async
)
async
=
create_async
(
obj
,
current
,
ptr
);
if
(
!
async
)
return
;
async
->
status
=
STATUS_PENDING
;
if
(
!
async
->
q
)
{
async_add_timeout
(
async
,
timeout
);
async_insert
(
q
,
async
);
}
}
}
else
if
(
async
)
destroy_async
(
async
);
else
set_error
(
STATUS_INVALID_PARAMETER
);
return
q
;
set_select_events
(
obj
,
serial_get_poll_events
(
obj
))
;
}
/* create a serial */
...
...
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