sealed class SafeSocketHandle : SafeHandleZeroOrMinusOneIsInvalid {
List<Thread> blocking_threads;
+ bool in_cleanup;
const int SOCKET_CLOSED = 10004;
#endif
if (blocking_threads != null) {
- int abort_attempts = 0;
- while (blocking_threads.Count > 0) {
- if (abort_attempts++ >= ABORT_RETRIES) {
- if (THROW_ON_ABORT_RETRIES)
- throw new Exception ("Could not abort registered blocking threads before closing socket.");
-
- // Attempts to close the socket safely failed.
- // We give up, and close the socket with pending blocking system calls.
- // This should not occur, nonetheless if it does this avoids an endless loop.
- break;
- }
-
- /*
- * This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
- * When this happens blocking_threads contains the current thread.
- * We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
- * before the blocking system call.
- */
- lock (blocking_threads) {
+ lock (blocking_threads) {
+ int abort_attempts = 0;
+ while (blocking_threads.Count > 0) {
+ if (abort_attempts++ >= ABORT_RETRIES) {
+ if (THROW_ON_ABORT_RETRIES)
+ throw new Exception ("Could not abort registered blocking threads before closing socket.");
+
+ // Attempts to close the socket safely failed.
+ // We give up, and close the socket with pending blocking system calls.
+ // This should not occur, nonetheless if it does this avoids an endless loop.
+ break;
+ }
+
+ /*
+ * This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
+ * When this happens blocking_threads contains the current thread.
+ * We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
+ * before the blocking system call.
+ */
if (blocking_threads.Count == 1 && blocking_threads[0] == Thread.CurrentThread)
break;
- }
- AbortRegisteredThreads ();
- // Sleep so other threads can resume
- Thread.Sleep (1);
+ // abort registered threads
+ foreach (var t in blocking_threads)
+ Socket.cancel_blocking_socket_operation (t);
+
+ // Sleep so other threads can resume
+ in_cleanup = true;
+ Monitor.Wait (blocking_threads, 100);
+ }
}
}
//If this NRE, we're in deep problems because Register Must have
lock (blocking_threads) {
blocking_threads.Remove (Thread.CurrentThread);
- }
- }
-
- void AbortRegisteredThreads () {
- if (blocking_threads == null)
- return;
-
- lock (blocking_threads) {
- foreach (var t in blocking_threads)
- Socket.cancel_blocking_socket_operation (t);
+ if (in_cleanup && blocking_threads.Count == 0)
+ Monitor.Pulse (blocking_threads);
}
}
}
mono_classes_cleanup (void);
void
-mono_class_layout_fields (MonoClass *klass);
+mono_class_layout_fields (MonoClass *klass, int instance_size);
void
mono_class_setup_interface_offsets (MonoClass *klass);
int i, blittable = TRUE;
guint32 real_size = 0;
guint32 packing_size = 0;
+ int instance_size;
gboolean explicit_size;
MonoClassField *field;
MonoGenericContainer *container = NULL;
}
}
- klass->instance_size = 0;
+ instance_size = 0;
if (!klass->rank)
klass->sizes.class_size = 0;
return;
}
}
- klass->instance_size += klass->parent->instance_size;
+ instance_size += klass->parent->instance_size;
klass->min_align = klass->parent->min_align;
/* we use |= since it may have been set already */
klass->has_references |= klass->parent->has_references;
blittable = klass->parent->blittable;
} else {
- klass->instance_size = sizeof (MonoObject);
+ instance_size = sizeof (MonoObject);
klass->min_align = 1;
}
return;
}
klass->packing_size = packing_size;
- real_size += klass->instance_size;
+ real_size += instance_size;
}
if (!top) {
if (explicit_size && real_size) {
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
}
klass->blittable = blittable;
+ if (!klass->instance_size)
+ klass->instance_size = instance_size;
mono_memory_barrier ();
klass->size_inited = 1;
klass->fields_inited = 1;
return;
}
if (explicit_size && real_size) {
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
}
if (mono_class_has_failure (klass))
return;
- mono_class_layout_fields (klass);
+ mono_class_layout_fields (klass, instance_size);
/*valuetypes can't be neither bigger than 1Mb or empty. */
if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
/*
* mono_class_layout_fields:
* @class: a class
+ * @instance_size: base instance size
*
* Compute the placement of fields inside an object or struct, according to
* the layout rules and set the following fields in @class:
* LOCKING: this is supposed to be called with the loader lock held.
*/
void
-mono_class_layout_fields (MonoClass *klass)
+mono_class_layout_fields (MonoClass *klass, int instance_size)
{
int i;
const int top = klass->field.count;
/*
* Compute field layout and total size (not considering static fields)
*/
-
switch (layout) {
case TYPE_ATTRIBUTE_AUTO_LAYOUT:
case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
real_size = field->offset + size;
}
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
- if (klass->instance_size & (klass->min_align - 1)) {
- klass->instance_size += klass->min_align - 1;
- klass->instance_size &= ~(klass->min_align - 1);
+ if (instance_size & (klass->min_align - 1)) {
+ instance_size += klass->min_align - 1;
+ instance_size &= ~(klass->min_align - 1);
}
}
break;
g_free (ref_bitmap);
}
- klass->instance_size = MAX (real_size, klass->instance_size);
- if (klass->instance_size & (klass->min_align - 1)) {
- klass->instance_size += klass->min_align - 1;
- klass->instance_size &= ~(klass->min_align - 1);
+ instance_size = MAX (real_size, instance_size);
+ if (instance_size & (klass->min_align - 1)) {
+ instance_size += klass->min_align - 1;
+ instance_size &= ~(klass->min_align - 1);
}
break;
}
* unaligned accesses otherwise. See #78990 for a testcase.
*/
if (mono_align_small_structs) {
- if (klass->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
- klass->min_align = MAX (klass->min_align, klass->instance_size - sizeof (MonoObject));
+ if (instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+ klass->min_align = MAX (klass->min_align, instance_size - sizeof (MonoObject));
}
}
+ if (klass->instance_size && !klass->image->dynamic) {
+ /* Might be already set using cached info */
+ g_assert (klass->instance_size == instance_size);
+ } else {
+ klass->instance_size = instance_size;
+ }
mono_memory_barrier ();
klass->size_inited = 1;
method = mono_class_get_method_from_name (klass, "BeginInvoke", -1);
g_assert (method != NULL);
- mono_threadpool_ms_begin_invoke (domain, (MonoObject*) load_value, method, NULL);
+ mono_threadpool_ms_begin_invoke (domain, (MonoObject*) load_value, method, NULL, &error);
+ if (!is_ok (&error)) {
+ g_warning ("Couldn't invoke System.Console cancel handler due to %s", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ }
}
static int need_cancel = FALSE;
ICALL_EXPORT MonoObject *
ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
{
+ MonoError error;
MonoClass *ac;
gint32 esize;
gpointer *ea;
+ MonoObject *result = NULL;
ac = (MonoClass *)arr->obj.vtable->klass;
esize = mono_array_element_size (ac);
ea = (gpointer*)((char*)arr->vector + (pos * esize));
- if (ac->element_class->valuetype)
- return mono_value_box (arr->obj.vtable->domain, ac->element_class, ea);
- else
- return (MonoObject *)*ea;
+ if (ac->element_class->valuetype) {
+ result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
+ mono_error_set_pending_exception (&error);
+ } else
+ result = (MonoObject *)*ea;
+ return result;
}
ICALL_EXPORT MonoObject *
ICALL_EXPORT MonoObject *
ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
{
+ MonoError error;
MonoDomain *domain = mono_object_domain (method);
MonoMethod *m = method->method;
MonoMethodSignature *sig = mono_method_signature (m);
MonoClassField* field = mono_class_get_field_from_name (k, str);
if (field) {
MonoClass *field_klass = mono_class_from_mono_type (field->type);
- if (field_klass->valuetype)
- result = mono_value_box (domain, field_klass, (char *)this_arg + field->offset);
- else
+ if (field_klass->valuetype) {
+ result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
+ mono_error_set_pending_exception (&error);
+ /* fallthru to cleanup */
+ } else
result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
out_args = mono_array_new (domain, mono_defaults.object_class, 1);
mono_ptr_array_destroy (tmp_array);
- if (!str)
- g_free (str);
+ g_free (str);
return res;
}
ICALL_EXPORT MonoObject*
mono_TypedReference_ToObject (MonoTypedRef* tref)
{
+ MonoError error;
+ MonoObject *result = NULL;
if (MONO_TYPE_IS_REFERENCE (tref->type)) {
MonoObject** objp = (MonoObject **)tref->value;
return *objp;
}
- return mono_value_box (mono_domain_get (), tref->klass, tref->value);
+ result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
ICALL_EXPORT MonoTypedRef
if (use_aot_wrappers) {
wrapper = mono_marshal_get_native_func_wrapper_aot (klass);
- this_obj = mono_value_box (mono_domain_get (), mono_defaults.int_class, &ftn);
+ this_obj = mono_value_box_checked (mono_domain_get (), mono_defaults.int_class, &ftn, &error);
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
} else {
memset (&piinfo, 0, sizeof (piinfo));
parse_unmanaged_function_pointer_attr (klass, &piinfo);
method = mono_get_delegate_invoke (klass);
g_assert (method);
- return mono_threadpool_ms_begin_invoke (mono_domain_get (), (MonoObject*) delegate, method, params);
+ MonoAsyncResult *result = mono_threadpool_ms_begin_invoke (mono_domain_get (), (MonoObject*) delegate, method, params, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
#ifndef DISABLE_JIT
void
mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass);
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, void* val, MonoError *error);
+
MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass);
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error);
#ifdef MONO_SMALL_CONFIG
#define MONO_IMT_SIZE 9
klass = mono_class_from_mono_type (type);
if (mono_class_is_nullable (klass))
- return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
+ return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass, error);
o = mono_object_new_checked (domain, klass, error);
return_val_if_nok (error, NULL);
* mono_nullable_box:
* @buf: The buffer representing the data to be boxed
* @klass: the type to box it as.
+ * @error: set on oerr
*
* Creates a boxed vtype or NULL from the Nullable structure pointed to by
- * @buf.
+ * @buf. On failure returns NULL and sets @error
*/
MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass)
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
-
+ mono_error_init (error);
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
- MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, error);
+ return_val_if_nok (error, NULL);
if (param_class->has_references)
mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
else
* boxed object in the arg array with the copy.
*/
MonoObject *orig = mono_array_get (params, MonoObject*, i);
- MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+ MonoObject *copy = mono_value_box_checked (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
mono_array_setref (params, i, copy);
}
if (!params)
return NULL;
- else
- return mono_value_box (mono_domain_get (), method->klass->cast_class, pa [0]);
+ else {
+ MonoObject *result = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, pa [0], &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+ }
}
if (!obj) {
else
o = obj;
} else if (method->klass->valuetype) {
- obj = mono_value_box (mono_domain_get (), method->klass, obj);
+ obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
if (exc) {
nullable = mono_object_new_checked (mono_domain_get (), method->klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- mono_nullable_init ((guint8 *)mono_object_unbox (nullable), mono_value_box (mono_domain_get (), method->klass->cast_class, obj), method->klass);
+ MonoObject *boxed = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_nullable_init ((guint8 *)mono_object_unbox (nullable), boxed, method->klass);
obj = mono_object_unbox (nullable);
}
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
{
- MONO_REQ_GC_UNSAFE_MODE;
-
MonoError error;
+ MonoObject *result = mono_value_box_checked (domain, klass, value, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_value_box_checked:
+ * @domain: the domain of the new object
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ * @error: set on error
+ *
+ * Returns: A newly created object which contains @value. On failure
+ * returns NULL and sets @error.
+ */
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, gpointer value, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
MonoObject *res;
int size;
MonoVTable *vtable;
+ mono_error_init (error);
+
g_assert (klass->valuetype);
if (mono_class_is_nullable (klass))
- return mono_nullable_box ((guint8 *)value, klass);
+ return mono_nullable_box ((guint8 *)value, klass, error);
vtable = mono_class_vtable (domain, klass);
if (!vtable)
return NULL;
size = mono_class_instance_size (klass);
- res = mono_object_new_alloc_specific_checked (vtable, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ res = mono_object_new_alloc_specific_checked (vtable, error);
+ return_val_if_nok (error, NULL);
size = size - sizeof (MonoObject);
#endif
#endif
if (klass->has_finalize) {
- mono_object_register_finalizer (res, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_object_register_finalizer (res, error);
+ return_val_if_nok (error, NULL);
}
return res;
}
klass = mono_class_from_mono_type (sig->params [i]);
- if (klass->valuetype)
- arg = mono_value_box (domain, klass, vpos);
- else
+ if (klass->valuetype) {
+ arg = mono_value_box_checked (domain, klass, vpos, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)vpos);
mono_array_setref (msg->args, i, arg);
mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
- if (field_class->valuetype)
- arg = mono_value_box (domain, field_class, val);
- else
+ if (field_class->valuetype) {
+ arg = mono_value_box_checked (domain, field_class, val, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)val);
MONO_API MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *klass, void* val);
static gboolean is_sre_method_on_tb_inst (MonoClass *klass);
static gboolean is_sre_ctor_on_tb_inst (MonoClass *klass);
+static gboolean type_is_reference (MonoType *type);
+
static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
return NULL;
}
+static MonoObject*
+load_cattr_value_boxed (MonoDomain *domain, MonoImage *image, MonoType *t, const char* p, const char** end, MonoError *error)
+{
+ mono_error_init (error);
+
+ gboolean is_ref = type_is_reference (t);
+
+ void *val = load_cattr_value (image, t, p, end, error);
+ if (!is_ok (error)) {
+ if (is_ref)
+ g_free (val);
+ return NULL;
+ }
+
+ if (is_ref)
+ return (MonoObject*)val;
+
+ MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (t), val, error);
+ g_free (val);
+ return boxed;
+}
+
static MonoObject*
create_cattr_typed_arg (MonoType *t, MonoObject *val, MonoError *error)
{
p += 2;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
MonoObject *obj;
- void *val;
- val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
- return;
- }
-
- obj = (MonoObject *)(type_is_reference (mono_method_signature (method)->params [i]) ?
- val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val));
+ obj = load_cattr_value_boxed (domain, image, mono_method_signature (method)->params [i], p, &p, error);
+ return_if_nok (error);
mono_array_setref (typedargs, i, obj);
-
- if (!type_is_reference (mono_method_signature (method)->params [i]))
- g_free (val);
}
named = p;
if (named_type == 0x53) {
MonoObject *obj;
MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
- void *val;
if (!field) {
g_free (name);
arginfo [j].type = field->type;
arginfo [j].field = field;
- val = load_cattr_value (image, field->type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (field->type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, field->type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (field->type))
- g_free (val);
+
} else if (named_type == 0x54) {
MonoObject *obj;
MonoType *prop_type;
MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
- void *val;
if (!prop || !prop->set) {
g_free (name);
arginfo [j].type = prop_type;
arginfo [j].prop = prop;
- val = load_cattr_value (image, prop_type, named, &named, error);
- if (!mono_error_ok (error)) {
- if (!type_is_reference (prop_type))
- g_free (val);
+ obj = load_cattr_value_boxed (domain, image, prop_type, named, &named, error);
+ if (!is_ok (error)) {
g_free (name);
return;
}
-
- obj = (MonoObject *)(type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val));
mono_array_setref (namedargs, j, obj);
- if (!type_is_reference (prop_type))
- g_free (val);
}
g_free (name);
}
}
klass->instance_size = MAX (klass->instance_size, real_size);
- mono_class_layout_fields (klass);
+ mono_class_layout_fields (klass, klass->instance_size);
}
static void
mparams[i] = *((gpointer *)params [i]);
} else {
/* runtime_invoke expects a boxed instance */
- if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i])))
- mparams[i] = mono_nullable_box ((guint8 *)params [i], klass);
- else
+ if (mono_class_is_nullable (mono_class_from_mono_type (sig->params [i]))) {
+ mparams[i] = mono_nullable_box ((guint8 *)params [i], klass, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
mparams[i] = params [i];
}
} else {
case MONO_TYPE_U8:
case MONO_TYPE_R4:
case MONO_TYPE_R8: {
- return mono_value_box (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject));
+ MonoObject *res = mono_value_box_checked (domain, mono_object_class (val), ((char*)val) + sizeof(MonoObject), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return res;
+
}
case MONO_TYPE_STRING: {
MonoString *str = (MonoString *) val;
static MonoObject*
int_to_object (MonoDomain *domain, int val)
{
- return mono_value_box (domain, mono_get_int32_class (), &val);
+ MonoError error;
+ MonoObject *result = mono_value_box_checked (domain, mono_get_int32_class (), &val, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
}
void
static void
wait_callback (gint fd, gint events, gpointer user_data)
{
+ MonoError error;
+
if (mono_runtime_is_shutting_down ())
return;
if (list && (events & EVENT_IN) != 0) {
MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_IN);
- if (job)
- mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job);
+ if (job) {
+ mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
+
}
if (list && (events & EVENT_OUT) != 0) {
MonoIOSelectorJob *job = get_job_for_event (&list, EVENT_OUT);
- if (job)
- mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job);
+ if (job) {
+ mono_threadpool_ms_enqueue_work_item (((MonoObject*) job)->vtable->domain, (MonoObject*) job, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
}
remove_fd = (events & EVENT_ERR) == EVENT_ERR;
static void
selector_thread (gpointer data)
{
+ MonoError error;
MonoGHashTable *states;
io_selector_running = TRUE;
memset (update, 0, sizeof (ThreadPoolIOUpdate));
}
- for (; list; list = mono_mlist_remove_item (list, list))
- mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list));
+ for (; list; list = mono_mlist_remove_item (list, list)) {
+ mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd);
threadpool_io->backend.remove_fd (fd);
mono_coop_mutex_unlock (&threadpool->active_threads_lock);
}
-void
-mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item)
+gboolean
+mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item, MonoError *error)
{
static MonoClass *threadpool_class = NULL;
static MonoMethod *unsafe_queue_custom_work_item_method = NULL;
- MonoError error;
MonoDomain *current_domain;
MonoBoolean f;
gpointer args [2];
+ mono_error_init (error);
g_assert (work_item);
if (!threadpool_class)
current_domain = mono_domain_get ();
if (current_domain == domain) {
- mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, error);
+ return_val_if_nok (error, FALSE);
} else {
mono_thread_push_appdomain_ref (domain);
if (mono_domain_set (domain, FALSE)) {
- mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (unsafe_queue_custom_work_item_method, NULL, args, error);
+ if (!is_ok (error)) {
+ mono_thread_pop_appdomain_ref ();
+ return FALSE;
+ }
mono_domain_set (current_domain, TRUE);
}
mono_thread_pop_appdomain_ref ();
}
+ return TRUE;
}
/* LOCKING: threadpool->domains_lock must be held */
}
MonoAsyncResult *
-mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params)
+mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params, MonoError *error)
{
static MonoClass *async_call_klass = NULL;
- MonoError error;
MonoMethodMessage *message;
MonoAsyncResult *async_result;
MonoAsyncCall *async_call;
mono_lazy_initialize (&status, initialize);
+ mono_error_init (error);
+
message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL);
- async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ async_call = (MonoAsyncCall*) mono_object_new_checked (domain, async_call_klass, error);
+ return_val_if_nok (error, NULL);
MONO_OBJECT_SETREF (async_call, msg, message);
MONO_OBJECT_SETREF (async_call, state, state);
async_result = mono_async_result_new (domain, NULL, async_call->state, NULL, (MonoObject*) async_call);
MONO_OBJECT_SETREF (async_result, async_delegate, target);
- mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result);
+ mono_threadpool_ms_enqueue_work_item (domain, (MonoObject*) async_result, error);
+ return_val_if_nok (error, NULL);
return async_result;
}
ves_icall_System_Threading_ThreadPool_ReportThreadStatus (MonoBoolean is_working)
{
// TODO
- mono_raise_exception (mono_get_exception_not_implemented (NULL));
+ MonoError error;
+ mono_error_set_not_implemented (&error, "");
+ mono_error_set_pending_exception (&error);
}
MonoBoolean
ves_icall_System_Threading_ThreadPool_PostQueuedCompletionStatus (MonoNativeOverlapped *native_overlapped)
{
/* This copy the behavior of the current Mono implementation */
- mono_raise_exception (mono_get_exception_not_implemented (NULL));
+ MonoError error;
+ mono_error_set_not_implemented (&error, "");
+ mono_error_set_pending_exception (&error);
return FALSE;
}
mono_threadpool_ms_cleanup (void);
MonoAsyncResult *
-mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params);
+mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMethod *method, gpointer *params, MonoError *error);
MonoObject *
mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc);
/* Internals */
-void
-mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item);
+gboolean
+mono_threadpool_ms_enqueue_work_item (MonoDomain *domain, MonoObject *work_item, MonoError *error);
#endif // _MONO_THREADPOOL_MICROSOFT_H_
mono_error_cleanup (&error); /* FIXME don't swallow the error */
}
- gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
+ gi->generic_sharing_context = alloc0_jit_info_data (domain, sizeof (MonoGenericSharingContext), async);
if (decode_value (p, &p)) {
/* gsharedvt */
MonoGenericSharingContext *gsctx = gi->generic_sharing_context;
} else if (type == VALUE_TYPE_ID_NULL) {
*(MonoObject**)addr = NULL;
} else if (type == MONO_TYPE_VALUETYPE) {
+ MonoError error;
guint8 *buf2;
gboolean is_enum;
MonoClass *klass;
g_free (vtype_buf);
return err;
}
- *(MonoObject**)addr = mono_value_box (d, klass, vtype_buf);
+ *(MonoObject**)addr = mono_value_box_checked (d, klass, vtype_buf, &error);
+ mono_error_cleanup (&error);
g_free (vtype_buf);
} else {
char *name = mono_type_full_name (t);
static ErrorCode
decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
{
+ MonoError error;
ErrorCode err;
int type = decode_byte (buf, &buf, limit);
g_free (nullable_buf);
return err;
}
- mono_nullable_init (addr, mono_value_box (domain, mono_class_from_mono_type (targ), nullable_buf), mono_class_from_mono_type (t));
+ MonoObject *boxed = mono_value_box_checked (domain, mono_class_from_mono_type (targ), nullable_buf, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return ERR_INVALID_OBJECT;
+ }
+ mono_nullable_init (addr, boxed, mono_class_from_mono_type (t));
g_free (nullable_buf);
*endbuf = buf;
return ERR_NONE;
static void
asm_writer_emit_start (MonoImageWriter *acfg)
{
+#if defined(TARGET_ASM_APPLE)
+ fprintf (acfg->fp, ".subsections_via_symbols\n");
+#endif
}
static int
/*
* Calling a non-vtype method with a vtype receiver, has to box.
*/
- *this_arg = mono_value_box (mono_domain_get (), klass, mp);
+ *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
else if (klass->valuetype)
/*
* Calling a vtype method with a vtype receiver
mono_error_set_exception_instance (error, (MonoException*) *exc);
if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class)
- return mono_value_box (domain, info->ret_box_class, retval);
+ return mono_value_box_checked (domain, info->ret_box_class, retval, error);
else
return *(MonoObject**)retval;
}
mono_arch_finish_dyn_call (info->dyn_call_info, buf);
if (info->ret_box_class)
- return mono_value_box (domain, info->ret_box_class, retval);
+ return mono_value_box_checked (domain, info->ret_box_class, retval, error);
else
return *(MonoObject**)retval;
}