src/core/unix-system-mutex.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 3433 d1e0154c45b3
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2008 INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Mathieu Lacage <mathieu.lacage.inria.fr>
    19  */
    20 
    21 #include <pthread.h>
    22 #include <string.h>
    23 #include <errno.h>
    24 #include "fatal-error.h"
    25 #include "system-mutex.h"
    26 #include "log.h"
    27 
    28 NS_LOG_COMPONENT_DEFINE ("SystemMutex");
    29 
    30 namespace ns3 {
    31 
    32 class SystemMutexPrivate {    
    33 public: 
    34   SystemMutexPrivate ();
    35   ~SystemMutexPrivate ();
    36 	
    37   void Lock (void);
    38   void Unlock (void);
    39 private:
    40   pthread_mutex_t m_mutex;
    41 };
    42 
    43 SystemMutexPrivate::SystemMutexPrivate ()
    44 {
    45   NS_LOG_FUNCTION_NOARGS ();
    46 
    47   pthread_mutexattr_t attr;
    48   pthread_mutexattr_init (&attr);
    49 //
    50 // Make this an error checking mutex.  This will check to see if the current
    51 // thread already owns the mutex before trying to lock it.  Instead of 
    52 // deadlocking it returns an error.  It will also check to make sure a thread
    53 // has previously called pthread_mutex_lock when it calls pthread_mutex_unlock.
    54 //
    55 // Linux and OS X (at least) have, of course chosen different names for the 
    56 // error checking flags just to make life difficult.
    57 //
    58 #if defined (PTHREAD_MUTEX_ERRORCHECK_NP)
    59   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
    60 #else
    61   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
    62 #endif
    63   pthread_mutex_init (&m_mutex, &attr);
    64 }
    65     
    66 SystemMutexPrivate::~SystemMutexPrivate() 
    67 {
    68   NS_LOG_FUNCTION_NOARGS ();
    69   pthread_mutex_destroy (&m_mutex);
    70 }
    71 	
    72   void 
    73 SystemMutexPrivate::Lock (void)
    74 {
    75   NS_LOG_FUNCTION_NOARGS ();
    76 
    77   int rc = pthread_mutex_lock (&m_mutex);
    78   if (rc != 0) 
    79     {
    80       NS_FATAL_ERROR ("SystemMutexPrivate::Lock()"
    81         "pthread_mutex_lock failed: " << rc << " = \"" << 
    82         strerror(rc) << "\"");
    83     }
    84 }
    85 	
    86   void
    87 SystemMutexPrivate::Unlock (void) 
    88 {
    89   NS_LOG_FUNCTION_NOARGS ();
    90 
    91   int rc = pthread_mutex_unlock (&m_mutex);
    92   if (rc != 0)
    93     {
    94       NS_FATAL_ERROR ("SystemMutexPrivate::Unlock()"
    95         "pthread_mutex_unlock failed: " << rc << " = \"" << 
    96         strerror(rc) << "\"");
    97     }
    98 }
    99 
   100 SystemMutex::SystemMutex() 
   101   : m_priv (new SystemMutexPrivate ())
   102 {
   103   NS_LOG_FUNCTION_NOARGS ();
   104 }
   105 
   106 SystemMutex::~SystemMutex() 
   107 {
   108   NS_LOG_FUNCTION_NOARGS ();
   109   delete m_priv;
   110 }
   111 
   112   void 
   113 SystemMutex::Lock() 
   114 {
   115   NS_LOG_FUNCTION_NOARGS ();
   116   m_priv->Lock ();
   117 }
   118 
   119   void 
   120 SystemMutex::Unlock() 
   121 {
   122   NS_LOG_FUNCTION_NOARGS ();
   123   m_priv->Unlock ();
   124 }  
   125 
   126 CriticalSection::CriticalSection (SystemMutex &mutex)
   127   : m_mutex(mutex)
   128 {
   129   NS_LOG_FUNCTION_NOARGS ();
   130   m_mutex.Lock ();
   131 }
   132 
   133 CriticalSection::~CriticalSection ()
   134 {
   135   NS_LOG_FUNCTION_NOARGS ();
   136   m_mutex.Unlock ();
   137 }
   138 
   139 } // namespace ns3