[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