[PATCH] async IO APCs call check_async_list() directly
Martin Wilck
Martin.Wilck at fujitsu-siemens.com
Thu Apr 4 10:30:17 CST 2002
PATCH: async-func.diff
This is an improvement over my previous patch (async-struct.diff)
in that it does not need the static function check_async_lists
in several source files anymore and still achieves DLL separation.
The idea is that all async I/O requests use check_async_list as callback function
anyway, so that there is no need to pass a function pointer.
I discussed the idea with Mike, and he seemed to like it.
Patch against: Wine CVS 2002/04/04, with my async-struct patch applied.
Test status: Compiles warnings.
Tested regular file async IO (ok).
Serial port async IO: a test would be desirable.
Modified files:
include : async.h (remove check_async_list)
server : protocol.def (add APC_ASYNC_IO APC type, remove func field for create_async)
async.h (remove func field in async struct)
async.c (remove references to func field)
thread.c (allow NULL function pointer for APC_ASYNC_IO)
scheduler : synchro.c (add check_async_list; call from call_apcs for APC_ASYNC_IO)
-- Martin
diff -ruNX ignore MW/wine/include/async.h TMP/wine/include/async.h
--- MW/wine/include/async.h Thu Apr 4 18:07:36 2002
+++ TMP/wine/include/async.h Thu Apr 4 18:08:56 2002
@@ -56,8 +56,6 @@
/* All functions declared static for Dll separation purposes */
-static void WINAPI check_async_list(async_private *asp, DWORD status);
-
inline static void finish_async( async_private *ovp )
{
if(ovp->prev)
@@ -87,7 +85,6 @@
req->overlapped = ovp;
req->type = ovp->type;
req->count = ovp->ops->get_count( ovp );
- req->func = check_async_list;
req->status = status;
ret = wine_server_call( req );
}
@@ -115,29 +112,6 @@
NtCurrentTeb()->pending_list = ovp;
return __register_async( ovp, status );
-}
-
-static void WINAPI check_async_list(async_private *asp, DWORD status)
-{
- async_private *ovp;
- DWORD ovp_status;
-
- for( ovp = NtCurrentTeb()->pending_list; ovp && ovp != asp; ovp = ovp->next );
-
- if(!ovp)
- return;
-
- if( status != STATUS_ALERTED )
- {
- ovp_status = status;
- ovp->ops->set_status (ovp, status);
- }
- else ovp_status = ovp->ops->get_status (ovp);
-
- if( ovp_status == STATUS_PENDING ) ovp->func( ovp ); /* ovp->func may change status */
-
- /* This will destroy all but PENDING requests */
- register_old_async( ovp );
}
#endif /* __WINE_ASYNC_H */
diff -ruNX ignore MW/wine/include/wine/server_protocol.h TMP/wine/include/wine/server_protocol.h
--- MW/wine/include/wine/server_protocol.h Thu Apr 4 18:07:36 2002
+++ TMP/wine/include/wine/server_protocol.h Thu Apr 4 17:49:50 2002
@@ -502,7 +502,7 @@
int type;
/* VARARG(args,ptrs); */
};
-enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC };
+enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC, APC_ASYNC_IO };
@@ -2278,7 +2278,6 @@
{
struct request_header __header;
handle_t handle;
- void* func;
int type;
void* overlapped;
int count;
@@ -3200,6 +3199,6 @@
struct get_window_properties_reply get_window_properties_reply;
};
-#define SERVER_PROTOCOL_VERSION 78
+#define SERVER_PROTOCOL_VERSION 81
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff -ruNX ignore MW/wine/scheduler/synchro.c TMP/wine/scheduler/synchro.c
--- MW/wine/scheduler/synchro.c Thu Apr 4 18:07:36 2002
+++ TMP/wine/scheduler/synchro.c Thu Apr 4 17:54:20 2002
@@ -30,7 +30,7 @@
#include "thread.h"
#include "winerror.h"
#include "wine/server.h"
-
+#include "async.h"
/***********************************************************************
* get_timeout
@@ -90,6 +90,34 @@
/***********************************************************************
+ * check_async_list
+ *
+ * Handle async I/O requests.
+ */
+static void WINAPI check_async_list(async_private *asp, DWORD status)
+{
+ async_private *ovp;
+ DWORD ovp_status;
+
+ for( ovp = NtCurrentTeb()->pending_list; ovp && ovp != asp; ovp = ovp->next );
+
+ if(!ovp)
+ return;
+
+ if( status != STATUS_ALERTED )
+ {
+ ovp_status = status;
+ ovp->ops->set_status (ovp, status);
+ }
+ else ovp_status = ovp->ops->get_status (ovp);
+
+ if( ovp_status == STATUS_PENDING ) ovp->func( ovp );
+
+ /* This will destroy all but PENDING requests */
+ register_old_async( ovp );
+}
+
+/***********************************************************************
* call_apcs
*
* Call outstanding APCs.
@@ -129,6 +157,9 @@
/* convert sec/usec to NT time */
DOSFS_UnixTimeToFileTime( (time_t)args[0], &ft, (DWORD)args[1] * 10 );
proc( args[2], ft.dwLowDateTime, ft.dwHighDateTime );
+ break;
+ case APC_ASYNC_IO:
+ check_async_list ( args[0], (DWORD) args[1]);
break;
default:
server_protocol_error( "get_apc_request: bad type %d\n", type );
diff -ruNX ignore MW/wine/server/async.c TMP/wine/server/async.c
--- MW/wine/server/async.c Thu Apr 4 18:07:36 2002
+++ TMP/wine/server/async.c Thu Apr 4 17:50:45 2002
@@ -64,7 +64,7 @@
{
/* fprintf(stderr,"notifying %p!\n",async->overlapped); */
async->status = status;
- thread_queue_apc(async->thread, NULL, async->func, APC_ASYNC, 1, 2, async->overlapped, status);
+ thread_queue_apc(async->thread, NULL, NULL, APC_ASYNC_IO, 1, 2, async->overlapped, status);
}
void destroy_async_queue( struct async_queue *q )
@@ -116,7 +116,7 @@
destroy_async(async);
}
-struct async *create_async(struct object *obj, struct thread *thread, void *func,
+struct async *create_async(struct object *obj, struct thread *thread,
void *overlapped)
{
struct async *async = (struct async *) malloc(sizeof(struct async));
@@ -128,7 +128,6 @@
async->obj = obj;
async->thread = thread;
- async->func = func;
async->overlapped = overlapped;
async->next = NULL;
async->prev = NULL;
@@ -165,7 +164,7 @@
if(req->status==STATUS_PENDING)
{
if(!async)
- async = create_async(obj, current, req->func, req->overlapped);
+ async = create_async(obj, current, req->overlapped);
if(async)
{
diff -ruNX ignore MW/wine/server/async.h TMP/wine/server/async.h
--- MW/wine/server/async.h Tue Apr 2 16:51:50 2002
+++ TMP/wine/server/async.h Thu Apr 4 17:50:57 2002
@@ -30,7 +30,6 @@
{
struct object *obj;
struct thread *thread;
- void *func;
void *overlapped;
unsigned int status;
struct timeval when;
@@ -51,7 +50,7 @@
struct async *find_async(struct async_queue *q, struct thread *thread, void *overlapped);
void async_insert(struct async_queue *q, struct async *async);
struct async *create_async(struct object *obj, struct thread *thread,
- void *func, void *overlapped);
+ void *overlapped);
void async_add_timeout(struct async *async, int timeout);
static inline void init_async_queue(struct async_queue *q)
{
diff -ruNX ignore MW/wine/server/protocol.def TMP/wine/server/protocol.def
--- MW/wine/server/protocol.def Thu Apr 4 18:07:36 2002
+++ TMP/wine/server/protocol.def Thu Apr 4 17:49:45 2002
@@ -412,7 +412,7 @@
int type; /* function type */
VARARG(args,ptrs); /* function arguments */
@END
-enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC };
+enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC, APC_ASYNC_IO };
/* Close a handle for the current process */
@@ -1618,7 +1618,6 @@
/* Create / reschedule an async I/O */
@REQ(register_async)
handle_t handle; /* handle to comm port, socket or file */
- void* func;
int type;
void* overlapped;
int count;
diff -ruNX ignore MW/wine/server/thread.c TMP/wine/server/thread.c
--- MW/wine/server/thread.c Tue Apr 2 16:51:51 2002
+++ TMP/wine/server/thread.c Thu Apr 4 17:37:22 2002
@@ -959,8 +959,9 @@
}
/* Optimization: ignore APCs that have a NULL func; they are only used
* to wake up a thread, but since we got here the thread woke up already.
+ * Exception: for APC_ASYNC_IO, func == NULL is legal.
*/
- if (apc->func) break;
+ if (apc->func || apc->type == APC_ASYNC_IO) break;
free( apc );
}
size = apc->nb_args * sizeof(apc->args[0]);
diff -ruNX ignore MW/wine/server/trace.c TMP/wine/server/trace.c
--- MW/wine/server/trace.c Thu Apr 4 18:07:36 2002
+++ TMP/wine/server/trace.c Thu Apr 4 17:49:50 2002
@@ -1846,7 +1846,6 @@
static void dump_register_async_request( const struct register_async_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
- fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " overlapped=%p,", req->overlapped );
fprintf( stderr, " count=%d,", req->count );
More information about the wine-devel
mailing list