I've tested an example from:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconmutex.asp

And it doesn't work correctly with Mono. It uses 2 mutex no control 4
threads, lets see each one:

t1Start: Waits to finish until all mutex are released
t2Start: Waits until mutex 1 is released
t3Start: Waits until any mutex is released (1 or 2)
t4Start: Waits until mutex 2 is released

The program launch the 4 threads and Release mutex 1 and then mutex 2.
The output of the program shows:

MutexSample.cs ...
 - Main Owns gM1 and gM2
t1Start started,  Mutex.WaitAll(Mutex[])
t2Start started,  gM1.WaitOne( )
t3Start started,  Mutex.WaitAny(Mutex[])
t4Start started,  gM2.WaitOne( )
 - Main releases gM1
t2Start finished, gM1.WaitOne( )
 - Main releases gM2
t4Start finished, gM2.WaitOne( )

And the program doesn't finish. As we can see only the threads t2 and t4
have finished, so the calls WaitAll and WaitAny of thread t1 and t3
don't work properly.

The code is attached. Is it a bug?

-- 

[aka Marble]
 Registered LiNUX user #140941  <>  http://counter.li.org/
 Socio #3274 de HispaLinux  <>  http://www.hispalinux.es
 Miembro de GPL URV  <>  http://www.gplurv.org
 GnuPG key: 0x0ED2CF9D  <>  pgp.escomposlinux.org
using System;
using System.Threading;

public class MutexSample{

   static Mutex            gM1;
   static Mutex            gM2;
   const int               ITERS   = 100;
   static AutoResetEvent   Event1  = new AutoResetEvent(false);
   static AutoResetEvent   Event2  = new AutoResetEvent(false);
   static AutoResetEvent   Event3  = new AutoResetEvent(false);
   static AutoResetEvent   Event4  = new AutoResetEvent(false);

   public static void Main(String[] args){

      Console.WriteLine("MutexSample.cs ...");
      gM1 = new Mutex(true,"MyMutex");
            // Create Mutext initialOwned, with name of "MyMutex".
       gM2 = new Mutex(true);                      
            // Create Mutext initialOwned, with no name.
      Console.WriteLine(" - Main Owns gM1 and gM2");

      AutoResetEvent[]    evs = new AutoResetEvent[4];
      evs[0] = Event1;
            // Event for t1.
      evs[1] = Event2;
            // Event for t2.
      evs[2] = Event3;
            // Event for t3.
      evs[3] = Event4;
            // Event for t4.

      MutexSample         tm  = new MutexSample( );
      Thread              t1  = new Thread(new ThreadStart(tm.t1Start));
      Thread              t2  = new Thread(new ThreadStart(tm.t2Start));
      Thread              t3  = new Thread(new ThreadStart(tm.t3Start));
      Thread              t4  = new Thread(new ThreadStart(tm.t4Start));
      t1.Start();
                // Calls Mutex.WaitAll(Mutex[] of gM1 and gM2).
      t2.Start();
                // Calls Mutex.WaitOne(Mutex gM1).
      t3.Start();
                // Calls Mutex.WaitAny(Mutex[] of gM1 and gM2).
      t4.Start();
                // Calls Mutex.WaitOne(Mutex gM2).

      Thread.Sleep(2000);
      Console.WriteLine(" - Main releases gM1");
      gM1.ReleaseMutex( );
        // t2 and t3 will end and signal.

      Thread.Sleep(1000);
      Console.WriteLine(" - Main releases gM2");
      gM2.ReleaseMutex( );
        // t1 and t4 will end and signal.

      WaitHandle.WaitAll(evs);
      // Waiting until all four threads signal that they are done.
      Console.WriteLine("... MutexSample.cs");
   }

   public void t1Start(){

      Console.WriteLine("t1Start started,  Mutex.WaitAll(Mutex[])");
      Mutex[]             gMs = new Mutex[2];
      gMs[0] = gM1;
               // Create and load an array of Mutex objects for WaitAll call.
      gMs[1] = gM2;
      Mutex.WaitAll(gMs);
               // Waits until both Mutex objects are released.
      Thread.Sleep(2000);
      Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[])");
      Event1.Set( );
              // AutoResetEvent.Set( ) flagging method is done.
   }

   public void t2Start(){
      Console.WriteLine("t2Start started,  gM1.WaitOne( )");
      gM1.WaitOne( );
            // Waits until Mutex gM1 is released.
      Console.WriteLine("t2Start finished, gM1.WaitOne( )");
      Event2.Set( );
            // AutoResetEvent.Set( ) flagging method is done.
   }

   public void t3Start(){
      Console.WriteLine("t3Start started,  Mutex.WaitAny(Mutex[])");
      Mutex[]             gMs = new Mutex[2];
      gMs[0] = gM1;
               // Create and load an array of Mutex objects for WaitAny call.
      gMs[1] = gM2;
      Mutex.WaitAny(gMs);
               // Waits until either Mutex object is released.
      Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");
      Event3.Set( );
               // AutoResetEvent.Set( ) flagging method is done.
   }

   public void t4Start(){
      Console.WriteLine("t4Start started,  gM2.WaitOne( )");
      gM2.WaitOne( );
            // Waits until Mutex gM2 is released.
      Console.WriteLine("t4Start finished, gM2.WaitOne( )");
      Event4.Set( );
            // AutoResetEvent.Set( ) flagging method is done.
   }
}

Attachment: signature.asc
Description: Esta parte del mensaje =?ISO-8859-1?Q?est=E1?= firmadadigitalmente

Reply via email to