#region Sync with metadata/object-internals.h
private InternalThread internal_thread;
object m_ThreadStartArg;
- private ExecutionContext ec_to_set;
#endregion
#pragma warning restore 414
CultureInfo current_culture;
CultureInfo current_ui_culture;
- // the name of current_thread and _ec is
+ // the name of current_thread is
// important because they are used by the runtime.
[ThreadStatic]
static Thread current_thread;
- /* The actual ExecutionContext of the thread. It's
- ThreadStatic so that it's not shared between
- AppDomains. */
- [ThreadStatic]
- static ExecutionContext _ec;
-
static internal CultureInfo default_culture;
static internal CultureInfo default_ui_culture;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern IntPtr Thread_internal (MulticastDelegate start);
- public Thread(ThreadStart start) {
- if(start==null) {
- throw new ArgumentNullException("Null ThreadStart");
- }
- m_Delegate=start;
- }
-
private Thread (InternalThread it) {
internal_thread = it;
}
}
}
- static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
-
- static private void ThreadStart_Context(Object state)
- {
- var t = (Thread)state;
- if (t.m_Delegate is ThreadStart)
- {
- ((ThreadStart)t.m_Delegate)();
- }
- else
- {
- ((ParameterizedThreadStart)t.m_Delegate)(t.m_ThreadStartArg);
- }
- }
-
- private void StartInternal ()
+ void StartInternal (IPrincipal principal, ref StackCrawlMark stackMark)
{
- current_thread = this;
-
- if (_ec != null) {
- ExecutionContext.Run (_ec, _ccb, (Object)this);
- return;
- }
-
- if (m_Delegate is ThreadStart) {
- ((ThreadStart) m_Delegate) ();
- } else {
- ((ParameterizedThreadStart) m_Delegate) (m_ThreadStartArg);
- }
- }
-
- public void Start() {
- StackCrawlMark stackMark = default (StackCrawlMark);
- // TODO: Use SetExecutionContextHelper to remove 2 of 3 levels of indirections
- ec_to_set = ExecutionContext.Capture (ref stackMark, ExecutionContext.CaptureOptions.IgnoreSyncCtx);
-
Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
// Thread_internal creates and starts the new thread,
- if (Thread_internal((ThreadStart) StartInternal) == (IntPtr) 0)
+ if (Thread_internal(m_Delegate) == IntPtr.Zero)
throw new SystemException ("Thread creation failed.");
- }
+ m_ThreadStartArg = null;
+ }
[MethodImplAttribute (MethodImplOptions.InternalCall)]
extern private static void SetState (InternalThread thread, ThreadState set);
static int GetProcessDefaultStackSize (int maxStackSize)
{
+ if (maxStackSize == 0)
+ return 0;
+
if (maxStackSize < 131072) // make sure stack is at least 128k big
return 131072;
return ManagedThreadId;
}
- public void Start (object parameter)
- {
- m_ThreadStartArg = parameter;
- Start ();
- }
-
internal CultureInfo GetCurrentUICultureNoAppX ()
{
return CultureInfo.CurrentUICulture;
thread = mono_thread_internal_current ();
- if (!ares->execution_context) {
- ares->original_context = NULL;
- } else {
- /* use captured ExecutionContext (if available) */
- MONO_OBJECT_SETREF (ares, original_context, mono_thread_get_execution_context ());
- mono_thread_set_execution_context (ares->execution_context);
- }
-
ac = (MonoAsyncCall*) ares->object_data;
if (!ac) {
thread->async_invoke_method = ((MonoDelegate*) ares->async_delegate)->method;
}
}
- /* restore original thread execution context if flow isn't suppressed, i.e. non null */
- if (ares->original_context) {
- mono_thread_set_execution_context (ares->original_context);
- ares->original_context = NULL;
- }
-
return res;
}
mono_g_hash_table_remove (thread_start_args, start_info->obj);
mono_threads_unlock ();
- mono_thread_set_execution_context (start_info->obj->ec_to_set);
- start_info->obj->ec_to_set = NULL;
-
g_free (start_info);
THREAD_DEBUG (g_message ("%s: start_wrapper for %"G_GSIZE_FORMAT, __func__,
internal->tid));
return ret;
}
-//static MonoClassField *execution_context_field;
-
-static MonoObject**
-get_execution_context_addr (void)
-{
- MonoDomain *domain = mono_domain_get ();
- guint32 offset = domain->execution_context_field_offset;
-
- if (!offset) {
- MonoClassField *field = mono_class_get_field_from_name (mono_defaults.thread_class, "_ec");
- g_assert (field);
-
- g_assert (mono_class_try_get_vtable (domain, mono_defaults.appdomain_class));
-
- mono_domain_lock (domain);
- offset = GPOINTER_TO_UINT (g_hash_table_lookup (domain->special_static_fields, field));
- mono_domain_unlock (domain);
- g_assert (offset);
-
- domain->execution_context_field_offset = offset;
- }
-
- return (MonoObject**) mono_get_special_static_data (offset);
-}
-
-MonoObject*
-mono_thread_get_execution_context (void)
-{
- return *get_execution_context_addr ();
-}
-
-void
-mono_thread_set_execution_context (MonoObject *ec)
-{
- *get_execution_context_addr () = ec;
-}
-
static gboolean has_tls_get = FALSE;
void