[runtime] Refactor AsyncResult creation with MonoAsyncCall
authorLudovic Henry <ludovic@xamarin.com>
Mon, 3 Aug 2015 16:40:27 +0000 (12:40 -0400)
committerLudovic Henry <ludovic@xamarin.com>
Mon, 3 Aug 2015 17:57:22 +0000 (13:57 -0400)
mcs/class/corlib/System.Runtime.Remoting.Messaging/AsyncResult.cs
mono/metadata/marshal.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/threadpool-ms.c

index ff43f8dc0d0301c6df76aaf30b3e6e175dcdb352..4d93c4a757557a8c1d3dddd7f8e7897d08acd63b 100644 (file)
@@ -46,7 +46,7 @@ public class AsyncResult : IAsyncResult, IMessageSink, IThreadPoolWorkItem {
        WaitHandle handle;
        object async_delegate;
        IntPtr data;
-       object object_data;
+       MonoAsyncCall async_call;
        bool sync_completed;
        bool completed;
        bool endinvoke_called;
index f31f17c46862ae1b1e649ab4ffa65167d1bf5ce9..b58eb166012b97a43a949d293728b2c2e33e761d 100644 (file)
@@ -2074,7 +2074,7 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
                        method = delegate->method;
 
                        msg = mono_method_call_message_new (mono_marshal_method_from_wrapper (method), params, NULL, &async_callback, &state);
-                       ares = mono_async_result_new (mono_domain_get (), NULL, state, NULL, NULL);
+                       ares = mono_async_result_new (mono_domain_get (), NULL, state, NULL);
                        MONO_OBJECT_SETREF (ares, async_delegate, (MonoObject *)delegate);
                        MONO_OBJECT_SETREF (ares, async_callback, (MonoObject *)async_callback);
                        MONO_OBJECT_SETREF (msg, async_result, ares);
index bd78a897bb07f4efc518c9be208efb60a2f69154..b41f2351351881a282c4bcdb54df22ed2cb44331 100644 (file)
@@ -266,13 +266,15 @@ typedef struct {
        MonoString *param_name;
 } MonoArgumentException;
 
+typedef struct _MonoAsyncCall MonoAsyncCall;
+
 typedef struct {
        MonoObject   object;
        MonoObject  *async_state;
        MonoObject  *handle;
        MonoObject  *async_delegate;
        gpointer    *data;
-       MonoObject  *object_data;
+       MonoAsyncCall  *async_call;
        MonoBoolean  sync_completed;
        MonoBoolean  completed;
        MonoBoolean  endinvoke_called;
@@ -353,7 +355,7 @@ typedef struct {
 } MonoMethodMessage;
 
 /* Keep in sync with the System.MonoAsyncCall */
-typedef struct {
+struct _MonoAsyncCall {
        MonoObject object;
        MonoMethodMessage *msg;
        MonoMethod *cb_method;
@@ -361,7 +363,7 @@ typedef struct {
        MonoObject *state;
        MonoObject *res;
        MonoArray *out_args;
-} MonoAsyncCall;
+};
 
 typedef struct {
        MonoObject obj;
@@ -630,8 +632,7 @@ MONO_COLD void mono_set_pending_exception (MonoException *exc);
 /* remoting and async support */
 
 MonoAsyncResult *
-mono_async_result_new      (MonoDomain *domain, HANDLE handle, 
-                            MonoObject *state, gpointer data, MonoObject *object_data);
+mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data);
 
 MonoObject *
 ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this);
index e4f8f928454147bfe8453a82867c8ebdb1ab46b4..2fac892d43c05aebe0c38dd872aab8b1e6b24c88 100644 (file)
@@ -5760,7 +5760,7 @@ mono_runtime_capture_context (MonoDomain *domain)
  *
  */
 MonoAsyncResult *
-mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data, MonoObject *object_data)
+mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data)
 {
        MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
        MonoObject *context = mono_runtime_capture_context (domain);
@@ -5771,7 +5771,6 @@ mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpo
        }
 
        res->data = data;
-       MONO_OBJECT_SETREF (res, object_data, object_data);
        MONO_OBJECT_SETREF (res, async_state, state);
        if (handle != NULL)
                MONO_OBJECT_SETREF (res, handle, (MonoObject *) mono_wait_handle_new (domain, handle));
@@ -5785,23 +5784,21 @@ mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpo
 MonoObject *
 ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this)
 {
-       MonoAsyncCall *ac;
        MonoObject *res;
 
        g_assert (this);
        g_assert (this->async_delegate);
 
-       ac = (MonoAsyncCall*) this->object_data;
-       if (!ac) {
+       if (!this->async_call) {
                res = mono_runtime_delegate_invoke (this->async_delegate, (void**) &this->async_state, NULL);
        } else {
                gpointer wait_event = NULL;
 
-               g_assert (ac->msg);
-               ac->msg->exc = NULL;
+               g_assert (this->async_call->msg);
+               this->async_call->msg->exc = NULL;
 
-               res = mono_message_invoke (this->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
-               MONO_OBJECT_SETREF (ac, res, res);
+               res = mono_message_invoke (this->async_delegate, this->async_call->msg, &this->async_call->msg->exc, &this->async_call->out_args);
+               MONO_OBJECT_SETREF (this->async_call, res, res);
 
                mono_monitor_enter ((MonoObject*) this);
 
@@ -5814,8 +5811,8 @@ ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult
 
                mono_monitor_exit ((MonoObject*) this);
 
-               if (ac->cb_method)
-                       mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &this, NULL);
+               if (this->async_call->cb_method)
+                       mono_runtime_invoke (this->async_call->cb_method, this->async_call->cb_target, (gpointer*) &this, NULL);
        }
 
        return res;
index 26ed2a1331958e33cbafd2a5e3cfc2e3cd654801..215740bcece16a280576794e0cc2e4be84be0e88 100644 (file)
@@ -1271,8 +1271,9 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
                MONO_OBJECT_SETREF (async_call, cb_target, async_callback);
        }
 
-       async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call);
+       async_result = mono_async_result_new (domain, NULL, async_call->state, NULL);
        MONO_OBJECT_SETREF (async_result, async_delegate, target);
+       MONO_OBJECT_SETREF (async_result, async_call, async_call);
 
 #ifndef DISABLE_SOCKETS
        if (mono_threadpool_ms_is_io (target, state))
@@ -1285,9 +1286,9 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet
 }
 
 MonoObject *
-mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc)
+mono_threadpool_ms_end_invoke (MonoAsyncResult *async_result, MonoArray **out_args, MonoObject **exc)
 {
-       MonoAsyncCall *ac;
+       MonoAsyncCall *async_call;
 
        g_assert (exc);
        g_assert (out_args);
@@ -1296,40 +1297,40 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
        *out_args = NULL;
 
        /* check if already finished */
-       mono_monitor_enter ((MonoObject*) ares);
+       mono_monitor_enter ((MonoObject*) async_result);
 
-       if (ares->endinvoke_called) {
+       if (async_result->endinvoke_called) {
                *exc = (MonoObject*) mono_get_exception_invalid_operation (NULL);
-               mono_monitor_exit ((MonoObject*) ares);
+               mono_monitor_exit ((MonoObject*) async_result);
                return NULL;
        }
 
-       MONO_OBJECT_SETREF (ares, endinvoke_called, 1);
+       MONO_OBJECT_SETREF (async_result, endinvoke_called, 1);
 
        /* wait until we are really finished */
-       if (ares->completed) {
-               mono_monitor_exit ((MonoObject *) ares);
+       if (async_result->completed) {
+               mono_monitor_exit ((MonoObject *) async_result);
        } else {
                gpointer wait_event;
-               if (ares->handle) {
-                       wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) ares->handle);
+               if (async_result->handle) {
+                       wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) async_result->handle);
                } else {
                        wait_event = CreateEvent (NULL, TRUE, FALSE, NULL);
                        g_assert(wait_event);
-                       MONO_OBJECT_SETREF (ares, handle, (MonoObject*) mono_wait_handle_new (mono_object_domain (ares), wait_event));
+                       MONO_OBJECT_SETREF (async_result, handle, (MonoObject*) mono_wait_handle_new (mono_object_domain (async_result), wait_event));
                }
-               mono_monitor_exit ((MonoObject*) ares);
+               mono_monitor_exit ((MonoObject*) async_result);
                MONO_PREPARE_BLOCKING;
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
                MONO_FINISH_BLOCKING;
        }
 
-       ac = (MonoAsyncCall*) ares->object_data;
-       g_assert (ac);
+       async_call = async_result->async_call;
+       g_assert (async_call);
+       *exc = async_call->msg->exc; /* FIXME: GC add write barrier */
+       *out_args = async_call->out_args;
 
-       *exc = ac->msg->exc; /* FIXME: GC add write barrier */
-       *out_args = ac->out_args;
-       return ac->res;
+       return async_call->res;
 }
 
 gboolean