Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnsafeQueueUserWorkItem and what exactly does "does not propagate the calling stack" mean?

Tags:

I am reading and learning about ThreadScheduler and articles around Tasks and came across the function ThreadPool.UnsafeQueueUserWorkItem used in one of the MSDN examples about own ThreadSchedulers. In the MSDN description about UnsafeQueueUserWorkItem there is a big warning that the function may be an security hole and that it "does not propagate the calling stack".

The only link is to QueueUserWorkItem which - from the name - seems to be the "safe counterpart"? but does not mention anything about calling stacks either.

What does that exactly mean to propagate a stack? Copy it over before the work starts? Why would another thread need the stack of the calling thread anyway? I would assume that they start with a fresh and empty stack. After all, when the thread function returns, it does not continue to execute the function scheduling the Task, right?

like image 384
Imi Avatar asked Jun 04 '13 19:06

Imi


People also ask

What is the use of ThreadPool QueueUserWorkItem method in C#?

QueueUserWorkItem(WaitCallback, Object) Queues a method for execution, and specifies an object containing data to be used by the method. The method executes when a thread pool thread becomes available.

Does Task use ThreadPool?

By default, TPL types like Task and Task<TResult> use thread pool threads to run tasks. You can also use the thread pool by calling ThreadPool.

What is a ThreadPool in C#?

Thread pool in C# is a collection of threads. It is used to perform tasks in the background. When a thread completes a task, it is sent to the queue wherein all the waiting threads are present. This is done so that it can be reused.

What is WaitCallback C#?

WaitCallback represents a callback method that you want to execute on a ThreadPool thread. Create the delegate by passing your callback method to the WaitCallback constructor. Your method must have the signature shown here. Queue the method for execution by passing the WaitCallback delegate to ThreadPool.


1 Answers

It is an implementation detail of CAS, Code Access Security. Which can check whether a thread has sufficient rights to perform an operation. It only matters if code runs in a restricted security environment, not running with full trust or in a sandbox.

The plumbing that makes this work is complicated and I can only approximate the way it works. The ExecutionContext class is key, it determines the security context in which code runs. Things get difficult when a thread that runs with restricted rights starts another thread. Clearly that other thread needs to run with the same kind of restrictions as the original thread. CAS depends on the being able to perform stack walks to discover restrictions. That's difficult on another thread, it has its own stack.

The ExecutionContext.Capture() method performs an essential role here. It makes a copy of the context of the calling thread, including making a stack walk to create a "compressed" stack of the security attributes discovered. The new thread then runs with that captured context.

ThreadPool.UnsafeQueueUserWorkItem() skips the Capture() call. The threadpool thread will run with the default execution context.

This is an optimization, Capture() is not a cheap method. It matters in the kind of program that depends on TP threads to get stuff done in a hurry. A web server jumps to mind. Also the kind of code that uses the method, you see it used in internal methods in the System.Net namespace for example.

Clearly it is unsafe, it doesn't run with the CAS restrictions of the originating thread.

like image 54
Hans Passant Avatar answered Oct 11 '22 11:10

Hans Passant