Loading...

gendarme@googlegroups.com

[Prev] Thread [Next]  |  [Prev] Date [Next]

[gendarme] DecorateThreadsRule Jesse Jones Tue Apr 28 05:06:56 2009

As I am sure everyone knows, writing threaded code is difficult. One  
of the things that makes it difficult is that it is difficult to know  
which code is actually running under multiple threads. This becomes  
especially problematic as the code evolves. So, the idea is that  
developers can decorate their code with attributes to indicate if it  
is threaded or non-threaded and use gendarme to ensure that they are  
using the attributes correctly.

Unfortunately there isn't a tidy division between threaded and non- 
threaded code: it's pretty common to have types which are useable from  
any thread, but instances of that type from only a single thread (e.g.  
winforms or most of the collections). So I'm thinking of three  
attributes:

* MainThreadAttribute - Indicates that the code can only be used from  
within the main thread. If the code has no threading attribute then  
this is the one that is normally assumed.

* MultiTheadAttribute - The code is fully thread safe.

* SingleThreadAttribute - Instances can be used with any thread, but  
not with multiple threads.

These attributes can be applied to classes, structs, interfaces,  
delegates, methods, properties, and events.

The rule would operate something like this:

for every method in the assemblies being checked do
     record all of the methods called (non-transitively) by the method
     record the non-externally visible single methods
     record the non-externally visible multi methods

     if the method is a thread root then
         if the method is decorated with single or multi then
             record it as a thread root
         elif the method is decorated with main then
             report a high severity defect
         else
             report a low severity defect
         end
     end
end

for all of the decorated thread roots do
     for every method (transitively) called by the root do
         if the method is not in the System or Mono namespaces then
             if the method is decorated with main then
                 report a high severity defect
             elif the method is not decorated with single or multi then
                 report a medium severity defect
             end
         end
     end
end

for all of the non-externally visible single methods do
     if the method is not (transitively) called from a thread root then
          report a low severity defect
     end
end

for all of the non-externally visible multi methods do
     if the method is not (transitively) called from a thread root then
          report a low severity defect
     end
end

where a thread root is a finalizer, a method passed to the  
System.Threading.Thread ctor, an externally visible method marked as  
single or multi, etc. There'd probably have to be something similar  
for delegates.

One problem with this is that we can't statically determine when it's  
safe to call single code from multi code. For this I am thinking of  
writing a second rule which reports a defect for public access single  
methods which do not have an Assert or Requires method which uses  
System.Thread. CurrentThread.ManagedThreadId, i.e. the method needs  
something like this:

     Contract.Requires(Thread.CurrentThread.ManagedThreadId ==  
m_threadID, "can only be used with a single thread");

Sometimes people do this with a helper so we might want another check  
for a call to a method with Thread and Assert/Check/Verify in the name  
or some such. Perhaps we also want to check for code which explicitly  
throws.

   -- Jesse


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Gendarme" group.
To post to this group, send email to [EMAIL PROTECTED]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/gendarme?hl=en
-~----------~----~----~----~------~----~------~--~---