+ 1 - 3 | § ¶Remoting tests
Today 100% of remoting unit tests passed. A clear sign that there are not enough tests.Novell street in Barcelona

Do you have one of these in Provo?
+ 3 - 1 | § ¶New Thread.Abort implementation
Miguel oficially anounced that we have a new implementation for Thread.Abort. This has been until now the source of many unstabilities in the runtime, specially in ASP.NET and in applications that use backgorund threads or the thread pool.The old implementation was using a signal to notify the thread that it had to be aborted. Upon receiving the signal, the thread would raise the ThreadAbortExcetpion, no matter which code it was running. The problem is that if the thread is running unmanaged code, it may be holding unmanaged locks, or it may leave some internal data structures in an undetermined state.
In the new implementation, we still use a signal to tell the thread that it has to be aborted, but it is handled in a different way:
- When a thread needs to be aborted, its state is set to AbortRequested and the thread is signaled using the abort signal.
- If the thread is running managed code when it gets the signal, the Abort exception will be thrown without any delay.
- If the thread is running unmanaged code, a special flag is set in the MonoThread that specifies that the thread needs to be interrupted. When the thread returns to managed code, that flag is automatically checked and the thread is aborted if needed.
Unmanaged methods that can block need a special handling. The most evident ones are the wait methods: WaitForSingleObject, WaitForMultipleObjects and Sleep. Although they run in unmanaged code they need to be abortable at any moment. What I've done is to implement the "Ex" version of those methods, which have an additional parameter "alertable" to specify if the wait can be canceled. The method QueueUserAPC can be used to cancel the wait, I've added this method to the io-layer.
The runtime has to check the result those methods and make sure that interruptions are correctly handled. Wait methods will return WAIT_IO_COMPLETION if they are externally interrumped. Other io-layer methods such as _wapi_accept will return a generic error.
There is also a basic support of Thread.Abort for Windows. In Windows, instead of using a signal to tell the thread that it has to be interrupted, it uses QueueUserAPC to enqueue a callback that will do the interruption check. However, since the APC queue is only checked in the wait methods, there is no guarantee that the thread will ever stop. This may happen if the thread never performs a managed-unmanaged transition after the abort is requested. This needs more work.
I've also reused all this infrastructure to implement Thread.Suspend and Thread.Stop (no, the Stop method does not exist in the Thread class, but it is used by the runtime to stop background threads. It does basically the same as Thread.Abort but without throwing the exception).
The problem with Thread.Suspend is that if the thread is suspended in unmanaged code holding an unmanaged lock, it will probably deadlock the whole runtime. To make sure this doesn't happen, the thread must be suspended when running managed code. the idea is to request an interruption of the thread using a signal (in fact the same signal used for thread.abort), and when it enters in a state in which it can be safely interrumped, just suspend it. However, it still doesn't work because it relies on SuspendThread from io-layer to finally suspend the thread, and this method is not working properly since it has deadlock problems with the garbage collector. The easy solution is to not use SuspendThread, and use instead a semaphore controlled at runtime level. Will work on this soon. Of course, if the thread holds managed locks it can still cause a deadlock, but this is a problem of the application, not the runtime.