AppliSec

Manu Cohen Yashar

WCF thread affinity and synchronization.

WCF does not promise thread affinity. This means that WCF does not promise that the thread that started the service operation execution will be the one who will finish the execution.  In case the operation waits on some wait handle (wait for IO or DB for example) the thread might return to the thread pool and when execution should resume another thread might do the work.

public class MyService : IContract

{

    public static object wait_handle;

    public int LongOperation()

    {

       Before();

 

       LongWait(); //Threads might be switched here

 

       After();

       return 0;

    }

 }

This fact enhance WCF scalability might  introduce interesting synchronization scenarios.

If the operation is synchronized using a monitor (Using statement) it means that a Sync_Handle is associated with the thread.

If the execution thread is switched (no thread affinity) the second thread does not have the sync handle and the code will wait. On the other hand the starting thread might be assigned to another WCF request (after it was sent back to the thread pool). This next request have the sync_handle, it would not wait and it might  cause damage to synchronized resources.

public class MyService : IContract

    {

        public static object wait_handle;

        public int LongOperation()

        {

            lock (wait_handle)

            {

                Before(); //Thread1 has the lock

 

                LongWait(); //Threads might be switched here

 

                After(); // Thread2 does not have the lock but
                            it runs.

                return 0;

            }           

        }

 

        public int SecondOperation()

        {

            // If accidently Thread1 is allocated it has the
               handle and would enter the lock.

            lock (wait_handle)

            {

                DoWork();

            }

            return 0;

        }

    }

The solution is simple.

Whene there is no thread affinity do not use monitor and the using statement. Use Events (autoReasetEvent or ManualResetEvent).  When WCF perform a thread switch the second thread can set the event and the synchronization will continue as planned.

Comments

Eran Stiller said:

Manu,

Could you please post an example in which the thread might actually switch in the middle of an operation?

# November 27, 2009 5:35 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: