BlackLib::BlackMutex Class Reference

Prevents accessing the same memory location at the same time from different threads. More...

#include <BlackMutex.h>

Public Types

enum  mutexMode {
  NonRecursive = 0,
  Recursive = 1
}
 

Public Member Functions

 BlackMutex (BlackMutex::mutexMode mm=BlackMutex::NonRecursive)
 Constructor of BlackMutex class. More...
 
virtual ~BlackMutex ()
 Destructor of BlackMutex class. More...
 
bool lock ()
 Locks the mutex. More...
 
bool tryLock ()
 Tries lock the mutex. More...
 
bool timedLock (unsigned int sec)
 Locks the mutex until the time expires. More...
 
bool unlock ()
 Unlocks the mutex. More...
 
bool isLocked ()
 Checks the mutex lock state. More...
 
bool isRecursive ()
 Checks the mutex recursiveness. More...
 
unsigned int getLockedCount ()
 Exports the mutex lock count. More...
 

Private Attributes

pthread_mutex_t mutex
 is used to hold the mutex posix data structure More...
 
unsigned int lockCount
 is used to hold the mutex lock count More...
 
mutexMode mode
 is used to hold the mutex mode property More...
 

Detailed Description

Prevents accessing the same memory location at the same time from different threads.

The mutex is generally used for thread synchronization. It prevents collisions and crashes and protects any objects,variables and part of your codes. It provides this with allowing to access a memory location to one thread at a time.

Warning
This class supports recursive mutex lock also. A thread can lock mutex more than once. If the unlock() function isn't called lock count times, the mutex won't unlocked.
Example
EXAMPLE PROJECT FILE TREE:

    myMutexProject
     |-> src
         |-> BlackLib
             |-> BlackDirectory
                 |-> BlackDirectory.cpp
                 |-> BlackDirectory.h
             |-> BlackThread
                 |-> BlackThread.cpp
                 |-> BlackThread.h
             |-> BlackMutex
                 |-> BlackMutex.cpp
                 |-> BlackMutex.h
             |-> BlackTime
                 |-> BlackTime.cpp
                 |-> BlackTime.h
             |-> BlackADC
                 |-> BlackADC.cpp
                 |-> BlackADC.h
             |-> BlackGPIO
                 |-> BlackGPIO.cpp
                 |-> BlackGPIO.h
             |-> BlackI2C
                 |-> BlackI2C.cpp
                 |-> BlackI2C.h
             |-> BlackPWM
                 |-> BlackPWM.cpp
                 |-> BlackPWM.h
             |-> BlackSPI
                 |-> BlackSPI.cpp
                 |-> BlackSPI.h
             |-> BlackUART
                 |-> BlackUART.cpp
                 |-> BlackUART.h
             |-> BlackCore.cpp
             |-> BlackCore.h
             |-> BlackDef.h
             |-> BlackErr.h
             |-> BlackLib.h
        |-> myMutexProject.cpp


If BlackLib source files are located in your project like above example project file tree, you have to include BlackMutex.h or another source files with adding this line to your project file (myMutexProject.cpp at the example):
#include "BlackLib/BlackMutex/BlackMutex.h"


If BlackLib source files are located at same level with your project file (myMutexProject.cpp at the example), you have to include BlackMutex.h or another source files with adding this line to your project file:

// Filename: myMutexProject.cpp
// Author: Yiğit Yüce - ygtyce@gmail.com
#include <iostream>
#include "BlackLib/BlackThread/BlackThread.h"
#include "BlackLib/BlackMutex/BlackMutex.h"
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task1 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 10 ; i++)
{
std::cout << ++number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task2 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 15 ; i++)
{
std::cout << --number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
int main()
{
myMutex = new BlackLib::BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Task1 doing the following operations:
// Global variable(number)'s current value: 1 2 3 4 5 6 7 8 9 10
// Task2 doing the following operations:
// Global variable(number)'s current value: 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5


You can use "using namespace BlackLib" also. You can get rid of writing "BlackLib::", with using this method.
// Filename: myMutexProject.cpp
// Author: Yiğit Yüce - ygtyce@gmail.com
#include <iostream>
#include "BlackLib/BlackThread/BlackThread.h"
#include "BlackLib/BlackMutex/BlackMutex.h"
using namespace BlackLib;
int number;
BlackMutex *myMutex;
class Task1 : public BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task1 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 10 ; i++)
{
std::cout << ++number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
class Task2 : public BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task2 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 15 ; i++)
{
std::cout << --number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
int main()
{
myMutex = new BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Task1 doing the following operations:
// Global variable(number)'s current value: 1 2 3 4 5 6 7 8 9 10
// Task2 doing the following operations:
// Global variable(number)'s current value: 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5

Member Enumeration Documentation

This enum is used to define mutex recursive mode.

Enumerator
NonRecursive 

enumeration for non-recursive type mutex

Recursive 

enumeration for recursive type mutex

Constructor & Destructor Documentation

BlackLib::BlackMutex::BlackMutex ( BlackMutex::mutexMode  mm = BlackMutex::NonRecursive)

Constructor of BlackMutex class.

This function initializes mutex.

Example
...
...
thread definitions, global variables etc.
...
...
...
int main()
{
// default is non-recursive mode
...
...
...
thread operations
...
...
return 0;
}
BlackLib::BlackMutex::~BlackMutex ( )
virtual

Destructor of BlackMutex class.

Member Function Documentation

unsigned int BlackLib::BlackMutex::getLockedCount ( )

Exports the mutex lock count.

Returns
number of lock count of mutex.
Example
...
...
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
for( int i = 0 ; i < 10 ; i++)
{
}
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
if( myMutex->isRecursive() )
{
for( int i=0 ; i<14 ; i++)
{
myMutex->lock();
}
}
std::cout << "Mutex locked " << myMutex->getLockedCount() << " times.\n";
for( int i = 0 ; i < 15 ; i++)
{
}
for( unsigned int i=0 ; i<myMutex->getLockedCount() ; i++)
{
myMutex->unlock();
}
}
};
...
...
...
int main()
{
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Mutex locked 15 times.
bool BlackLib::BlackMutex::isLocked ( )

Checks the mutex lock state.

This function checks the lock status of mutex.

Returns
true if mutex is locked else false.
Example
...
...
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
for( int i = 0 ; i < 10 ; i++)
{
}
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
for( int i = 0 ; i < 15 ; i++)
{
}
myMutex->unlock();
}
};
...
...
...
int main()
{
myMutex = new BlackLib::BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
std::cout << "Mutex is locked? : " << std::boolalpha << myMutex->isLocked() << std::endl;
std::cout << "Mutex is locked? : " << std::boolalpha << myMutex->isLocked() << std::endl;
return 0;
}
// Possible Output:
// Mutex is locked? : true
// Mutex is locked? : false
bool BlackLib::BlackMutex::isRecursive ( )

Checks the mutex recursiveness.

Example
...
...
thread definitions, global variables etc.
...
...
...
int main()
{
// default is non-recursive mode
...
...
...
thread operations
std::cout << "myMutex is recursive? : " << std::boolalpha << myMutex.isRecursive() << std::endl;
std::cout << "myMutexPtr is recursive? : " << std::boolalpha << myMutexPtr->isRecursive() << std::endl;
...
...
return 0;
}
// Possible Output:
// myMutex is recursive? : false
// myMutexPtr is recursive? : true
bool BlackLib::BlackMutex::lock ( )

Locks the mutex.

This function locks the mutex. If mutex is locked before it waits until mutex is unlocked.

Returns
true if mutex lock is success else false.
Warning
This function waits until the mutex locked so it blocks the thread until mutex lock is successful.
Example
...
...
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task1 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 10 ; i++)
{
std::cout << ++number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task2 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 15 ; i++)
{
std::cout << --number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
...
...
...
int main()
{
myMutex = new BlackLib::BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Task1 doing the following operations:
// Global variable(number)'s current value: 1 2 3 4 5 6 7 8 9 10
// Task2 doing the following operations:
// Global variable(number)'s current value: 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5
bool BlackLib::BlackMutex::timedLock ( unsigned int  sec)

Locks the mutex until the time expires.

This function tries lock the mutex. If mutex is already locked, this function waits mutex to be unlocked and tries to lock until the time expires. If time is expired and the mutex still can't be lockable, the function returns false.

Parameters
[in]sectime in seconds
Returns
true if mutex lock is success until the time expires else false.
Example
...
...
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task1 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 10 ; i++)
{
std::cout << ++number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
if( myMutex->timedLock(5) )
{
std::cout << "Task2 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 15 ; i++)
{
std::cout << --number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
else
{
std::cout << "Task2 couldn\'t lock the mutex. ";
}
}
};
...
...
...
int main()
{
myMutex = new BlackLib::BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Task1 doing the following operations:
// Global variable(number)'s current value: 1 2 3 4 5 6 7 8 9 10
// Task2 couldn't lock the mutex.
bool BlackLib::BlackMutex::tryLock ( )

Tries lock the mutex.

This function tries lock the mutex. This function does not wait until lock the mutex. If mutex is already locked, this function returns immediatly with false value.

Returns
true if mutex lock is success else false.
Example
...
...
int number;
class Task1 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
myMutex->lock();
std::cout << "Task1 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 10 ; i++)
{
std::cout << ++number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
};
class Task2 : public BlackLib::BlackThread
{
public:
void onStartHandler()
{
if( myMutex->tryLock() )
{
std::cout << "Task2 doing the following operations: \n";
std::cout << "Global variable(number)\'s current value: \n";
for( int i = 0 ; i < 15 ; i++)
{
std::cout << --number << " ";
}
std::cout << std::endl;
myMutex->unlock();
}
else
{
std::cout << "Task2 couldn\'t lock the mutex. ";
}
}
};
...
...
...
int main()
{
myMutex = new BlackLib::BlackMutex();
number = 0;
Task1 *t1 = new Task1();
Task2 *t2 = new Task2();
t1->run();
t2->run();
return 0;
}
// Possible Output:
// Task1 doing the following operations:
// Global variable(number)'s current value: 1 2 3 4 5 6 Task2 couldn't lock the mutex. 7 8 9 10
bool BlackLib::BlackMutex::unlock ( )

Unlocks the mutex.

This function unlocks the mutex. If mutex is already unlocked it does nothing.

Returns
true if mutex unlock is success else false.
Warning
This function waits until the mutex unlocked so it blocks the thread until mutex unlock is successful.
Example
Example usage is shown in BlackMutex::lock() and BlackMutex::tryLock() functions' example.

Member Data Documentation

unsigned int BlackLib::BlackMutex::lockCount
private

is used to hold the mutex lock count

mutexMode BlackLib::BlackMutex::mode
private

is used to hold the mutex mode property

pthread_mutex_t BlackLib::BlackMutex::mutex
private

is used to hold the mutex posix data structure


The documentation for this class was generated from the following files: