(file) Return to Mutex.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/Mutex.cpp between version 1.9.16.2 and 1.12

version 1.9.16.2, 2007/09/11 18:18:09 version 1.12, 2008/08/15 17:24:52
Line 40 
Line 40 
  
 //============================================================================== //==============================================================================
 // //
 // Mutex implementation with PTHREAD_MUTEX_RECURSIVE feature.  // PEGASUS_HAVE_PTHREADS
 // //
 //============================================================================== //==============================================================================
  
 #if defined(PEGASUS_HAVE_PTHREADS) && defined(PEGASUS_HAVE_RECURSIVE_MUTEXES)  #if defined(PEGASUS_HAVE_PTHREADS)
  
 static Once _once = PEGASUS_ONCE_INITIALIZER; static Once _once = PEGASUS_ONCE_INITIALIZER;
 static pthread_mutexattr_t _attr; static pthread_mutexattr_t _attr;
Line 104 
Line 104 
     }     }
 } }
  
 void Mutex::try_lock()  Boolean Mutex::try_lock()
 { {
     PEGASUS_DEBUG_ASSERT(_magic);     PEGASUS_DEBUG_ASSERT(_magic);
  
     int r = pthread_mutex_trylock(&_rep.mutex);     int r = pthread_mutex_trylock(&_rep.mutex);
     if (r == -1)     if (r == -1)
         r=errno;         r=errno;
     switch (r)  
       if (r == 0)
     {     {
         case 0:  
 #if defined(PEGASUS_DEBUG) #if defined(PEGASUS_DEBUG)
             _rep.count++;             _rep.count++;
 #endif #endif
             break;          return true;
       }
  
         case EBUSY:      if (r == EBUSY)
             throw AlreadyLocked(Threads::self());      {
           return false;
       }
  
         default:  
             throw WaitFailed(Threads::self());             throw WaitFailed(Threads::self());
     }     }
 }  
  
 void Mutex::timed_lock(Uint32 milliseconds)  Boolean Mutex::timed_lock(Uint32 milliseconds)
 { {
     PEGASUS_DEBUG_ASSERT(_magic);     PEGASUS_DEBUG_ASSERT(_magic);
  
Line 149 
Line 150 
         int r=pthread_mutex_trylock(&_rep.mutex);         int r=pthread_mutex_trylock(&_rep.mutex);
         if (r == -1)         if (r == -1)
             r = errno;             r = errno;
         switch (r)  
         {  
             case 0:  
 #if defined(PEGASUS_DEBUG)  
                 _rep.count++;  
 #endif  
                 return;  
  
             case EBUSY:          if (r == 0)
           {
               break;
           }
           else if (r == EBUSY)
             {             {
                 gettimeofday(&now, NULL);                 gettimeofday(&now, NULL);
  
                 if (Time::subtract(&remaining, &finish, &now))                 if (Time::subtract(&remaining, &finish, &now))
                     throw TimeOut(Threads::self());              {
                   return false;
               }
  
                 Threads::yield();                 Threads::yield();
                 break;  
             }             }
           else
             default:          {
                 throw WaitFailed(Threads::self());                 throw WaitFailed(Threads::self());
         }         }
     }     }
   
   #if defined(PEGASUS_DEBUG)
       _rep.count++;
   #endif
       return true;
 } }
  
 void Mutex::unlock() void Mutex::unlock()
Line 187 
Line 191 
         throw Permission(Threads::self());         throw Permission(Threads::self());
 } }
  
 #if defined(PEGASUS_OS_LINUX)  #if defined(PEGASUS_OS_LINUX) || \
       (defined(PEGASUS_OS_ZOS) && !(__TARGET_LIB__ < 0x41090000))
 void Mutex::reinitialize() void Mutex::reinitialize()
 { {
     pthread_mutex_init(&_rep.mutex, &_attr);     pthread_mutex_init(&_rep.mutex, &_attr);
Line 197 
Line 202 
 } }
 #endif #endif
  
 #endif /* PEGASUS_HAVE_PTHREADS && PEGASUS_HAVE_RECURSIVE_MUTEXES */  #endif /* PEGASUS_HAVE_PTHREADS */
   
 //==============================================================================  
 //  
 // Mutex implementation without PTHREAD_MUTEX_RECURSIVE feature.  
 //  
 //==============================================================================  
   
 #if defined(PEGASUS_HAVE_PTHREADS) && !defined(PEGASUS_HAVE_RECURSIVE_MUTEXES)  
   
 Mutex::Mutex()  
 {  
     pthread_mutex_init(&_rep.mutex, NULL);  
     pthread_cond_init(&_rep.cond, NULL);  
     _rep.owner = 0;  
     _rep.count = 0;  
 }  
   
 Mutex::Mutex(RecursiveTag)  
 {  
     _rep.recursive = 1;  
     pthread_mutex_init(&_rep.mutex, NULL);  
     pthread_cond_init(&_rep.cond, NULL);  
     _rep.owner = 0;  
     _rep.count = 0;  
 }  
   
 Mutex::Mutex(NonRecursiveTag)  
 {  
     _rep.recursive = 0;  
     pthread_mutex_init(&_rep.mutex, NULL);  
 }  
   
 Mutex::~Mutex()  
 {  
     PEGASUS_DEBUG_ASSERT(_magic);  
     pthread_mutex_destroy(&_rep.mutex);  
   
     if (_rep.recursive)  
         pthread_cond_destroy(&_rep.cond);  
 }  
   
 void Mutex::lock()  
 {  
     PEGASUS_DEBUG_ASSERT(_magic);  
   
     if (_rep.recursive)  
     {  
         pthread_t self = pthread_self();  
   
         pthread_mutex_lock(&_rep.mutex);  
         {  
             if (_rep.count == 0)  
             {  
                 _rep.owner = self;  
             }  
             else if (!pthread_equal(_rep.owner, self))  
             {  
                 while (_rep.count > 0)  
                     pthread_cond_wait(&_rep.cond, &_rep.mutex);  
   
                 _rep.owner = self;  
             }  
   
             _rep.count++;  
         }  
         pthread_mutex_unlock(&_rep.mutex);  
     }  
     else  
     {  
         if (pthread_mutex_lock(&_rep.mutex) != 0)  
         {  
             throw WaitFailed(Threads::self());  
         }  
     }  
 }  
   
 void Mutex::try_lock()  
 {  
     PEGASUS_DEBUG_ASSERT(_magic);  
   
     if (_rep.recursive)  
     {  
         pthread_t self = pthread_self();  
   
         pthread_mutex_lock(&_rep.mutex);  
         {  
             if (_rep.count == 0)  
             {  
                 _rep.owner = self;  
                 _rep.count = 1;  
             }  
             else if (pthread_equal(_rep.owner, self))  
             {  
                 _rep.count++;  
             }  
             else  
             {  
                 pthread_mutex_unlock(&_rep.mutex);  
                 throw AlreadyLocked(Threads::self());  
             }  
         }  
         pthread_mutex_unlock(&_rep.mutex);  
     }  
     else  
     {  
         int r = pthread_mutex_trylock(&_rep.mutex);  
   
         if (r == -1)  
             r = errno;  
   
         switch (r)  
         {  
             case 0:  
                 break;  
   
             case EBUSY:  
                 throw AlreadyLocked(Threads::self());  
   
             default:  
                 throw WaitFailed(Threads::self());  
         }  
     }  
 }  
   
 void Mutex::timed_lock(Uint32 milliseconds)  
 {  
     PEGASUS_DEBUG_ASSERT(_magic);  
   
     if (_rep.recursive)  
     {  
         pthread_t self = pthread_self();  
   
         pthread_mutex_lock(&_rep.mutex);  
         {  
             if (_rep.count == 0)  
             {  
                 _rep.owner = self;  
             }  
             else if (!pthread_equal(_rep.owner, self))  
             {  
                 timespec ts;  
                 clock_gettime(CLOCK_REALTIME, &ts);  
   
                 ts.tv_sec += milliseconds / 1000;  
                 ts.tv_nsec += (milliseconds % 1000) * 1000000;  
   
                 while (_rep.count > 0)  
                 {  
                     if (pthread_cond_timedwait(  
                         &_rep.cond, &_rep.mutex, &ts) != 0)  
                     {  
                         pthread_mutex_unlock(&_rep.mutex);  
                         throw TimeOut(Threads::self());  
                     }  
                 }  
   
                 _rep.owner = self;  
             }  
   
             _rep.count++;  
         }  
         pthread_mutex_unlock(&_rep.mutex);  
     }  
     else  
     {  
         struct timeval now;  
         struct timeval finish;  
         struct timeval remaining;  
         {  
             Uint32 usec;  
             gettimeofday(&finish, NULL);  
             finish.tv_sec += (milliseconds / 1000 );  
             milliseconds %= 1000;  
             usec = finish.tv_usec + ( milliseconds * 1000 );  
             finish.tv_sec += (usec / 1000000);  
             finish.tv_usec = usec % 1000000;  
         }  
   
         for (;;)  
         {  
             int r = pthread_mutex_trylock(&_rep.mutex);  
   
             if (r == -1)  
                 r = errno;  
   
             switch (r)  
             {  
                 case 0:  
                     return;  
   
                 case EBUSY:  
                 {  
                     gettimeofday(&now, NULL);  
   
                     if (Time::subtract(&remaining, &finish, &now))  
                         throw TimeOut(Threads::self());  
   
                     Threads::yield();  
                     break;  
                 }  
   
                 default:  
                     throw WaitFailed(Threads::self());  
             }  
         }  
     }  
 }  
   
 void Mutex::unlock()  
 {  
     PEGASUS_DEBUG_ASSERT(_magic);  
   
     if (_rep.recursive)  
     {  
         pthread_t self = pthread_self();  
   
         pthread_mutex_lock(&_rep.mutex);  
         {  
             // If not locked or if calling thread is not the locker.  
   
             if (_rep.count == 0 || !pthread_equal(_rep.owner, self))  
                 PEGASUS_DEBUG_ASSERT(0);  
   
             _rep.count--;  
             _rep.owner = 0;  
             pthread_cond_signal(&_rep.cond);  
         }  
         pthread_mutex_unlock(&_rep.mutex);  
     }  
     else  
     {  
         if (pthread_mutex_unlock(&_rep.mutex) != 0)  
             throw Permission(Threads::self());  
     }  
 }  
   
 #endif /* PEGASUS_HAVE_PTHREADS && !PEGASUS_HAVE_RECURSIVE_MUTEXES */  
  
 //============================================================================== //==============================================================================
 // //
Line 485 
Line 253 
     _rep.count++;     _rep.count++;
 } }
  
 void Mutex::try_lock()  Boolean Mutex::try_lock()
 { {
     PEGASUS_DEBUG_ASSERT(_magic);     PEGASUS_DEBUG_ASSERT(_magic);
  
     DWORD rc = WaitForSingleObject(_rep.handle, 0);     DWORD rc = WaitForSingleObject(_rep.handle, 0);
  
     if (rc == WAIT_TIMEOUT)     if (rc == WAIT_TIMEOUT)
         throw AlreadyLocked(Threads::self());      {
           return false;
       }
  
     if (rc == WAIT_FAILED)     if (rc == WAIT_FAILED)
       {
         throw WaitFailed(Threads::self());         throw WaitFailed(Threads::self());
       }
  
     _rep.count++;     _rep.count++;
       return true;
 } }
  
 void Mutex::timed_lock(Uint32 milliseconds)  Boolean Mutex::timed_lock(Uint32 milliseconds)
 { {
     PEGASUS_DEBUG_ASSERT(_magic);     PEGASUS_DEBUG_ASSERT(_magic);
  
     DWORD rc = WaitForSingleObject(_rep.handle, milliseconds);     DWORD rc = WaitForSingleObject(_rep.handle, milliseconds);
  
     if (rc == WAIT_TIMEOUT)     if (rc == WAIT_TIMEOUT)
         throw TimeOut(Threads::self());          return false;
  
     if (rc == WAIT_FAILED)     if (rc == WAIT_FAILED)
         throw WaitFailed(Threads::self());         throw WaitFailed(Threads::self());
  
     _rep.count++;     _rep.count++;
       return true;
 } }
  
 void Mutex::unlock() void Mutex::unlock()


Legend:
Removed from v.1.9.16.2  
changed lines
  Added in v.1.12

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2