2006-08-09 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 9 Aug 2006 21:13:11 +0000 (21:13 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 9 Aug 2006 21:13:11 +0000 (21:13 -0000)
* mcs/class/System/System.Diagnostics/Process.cs: add support for 2.0
asynchronous reads on stdout and stderr.

* mono/mono/metadata/threadpool.c: treat pipes from process
asynchronous reads as sockets when reading from them, so we get
select/poll or epoll to wait for data.

svn path=/trunk/mono/; revision=63565

mono/metadata/ChangeLog
mono/metadata/threadpool.c

index 4621d6750cdd5bc4bf5063b426a07751e7c4cd20..c059de273ae6ec65e6ef0a48335a7eccf4ac1b46 100644 (file)
@@ -1,3 +1,9 @@
+2006-08-09 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * threadpool.c: treat pipes from process asynchronous reads as sockets
+       when reading from them, so we get select/poll or epoll to wait for
+       data.
+
 2006-08-07  Sebastien Pouliot  <sebatien@ximian.com>
 
        * loader.c: Fix a typo (CID #233) in the null check.
index abf51355b138426d6b78d28dbc5adacace601c4d..a7caeddff0e326c65d29cc6cf3744bb086274eb2 100644 (file)
@@ -119,6 +119,7 @@ static GList *async_io_queue = NULL;
 
 static MonoClass *async_call_klass;
 static MonoClass *socket_async_call_klass;
+static MonoClass *process_async_call_klass;
 
 #define INIT_POLLFD(a, b, c) {(a)->fd = b; (a)->events = c; (a)->revents = 0;}
 enum {
@@ -131,6 +132,7 @@ enum {
        AIO_OP_SENDTO,
        AIO_OP_RECV_JUST_CALLBACK,
        AIO_OP_SEND_JUST_CALLBACK,
+       AIO_OP_READPIPE,
        AIO_OP_LAST
 };
 
@@ -180,6 +182,7 @@ get_event_from_state (MonoSocketAsyncResult *state)
        case AIO_OP_RECEIVE:
        case AIO_OP_RECV_JUST_CALLBACK:
        case AIO_OP_RECEIVEFROM:
+       case AIO_OP_READPIPE:
                return MONO_POLLIN;
        case AIO_OP_SEND:
        case AIO_OP_SEND_JUST_CALLBACK:
@@ -232,8 +235,6 @@ async_invoke_io_thread (gpointer data)
                if (state) {
                        InterlockedDecrement (&pending_io_items);
                        ar = state->ares;
-                       /* worker threads invokes methods in different domains,
-                        * so we need to set the right domain here */
                        switch (state->operation) {
                        case AIO_OP_RECEIVE:
                                state->total = ICALL_RECV (state);
@@ -243,6 +244,8 @@ async_invoke_io_thread (gpointer data)
                                break;
                        }
 
+                       /* worker threads invokes methods in different domains,
+                        * so we need to set the right domain here */
                        domain = ((MonoObject *)ar)->vtable->domain;
                        mono_thread_push_appdomain_ref (domain);
                        if (mono_domain_set (domain, FALSE)) {
@@ -877,7 +880,7 @@ socket_io_filter (MonoObject *target, MonoObject *state)
 
        if (socket_async_call_klass == NULL) {
                klass = target->vtable->klass;
-               /* Check if it's SocketAsyncCall in System
+               /* Check if it's SocketAsyncCall in System.Net.Sockets
                 * FIXME: check the assembly is signed correctly for extra care
                 */
                if (klass->name [0] == 'S' && strcmp (klass->name, "SocketAsyncCall") == 0 
@@ -886,10 +889,20 @@ socket_io_filter (MonoObject *target, MonoObject *state)
                        socket_async_call_klass = klass;
        }
 
+       if (process_async_call_klass == NULL) {
+               klass = target->vtable->klass;
+               /* Check if it's AsyncReadHandler in System.Diagnostics.Process
+                * FIXME: check the assembly is signed correctly for extra care
+                */
+               if (klass->name [0] == 'A' && strcmp (klass->name, "AsyncReadHandler") == 0 
+                               && strcmp (mono_image_get_name (klass->image), "System") == 0
+                               && klass->nested_in && strcmp (klass->nested_in->name, "Process") == 0)
+                       process_async_call_klass = klass;
+       }
        /* return both when socket_async_call_klass has not been seen yet and when
         * the object is not an instance of the class.
         */
-       if (target->vtable->klass != socket_async_call_klass)
+       if (target->vtable->klass != socket_async_call_klass && target->vtable->klass != process_async_call_klass)
                return FALSE;
 
        op = sock_res->operation;