fintp_utils
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ThreadingUtils.h
Go to the documentation of this file.
1 /*
2 * FinTP - Financial Transactions Processing Application
3 * Copyright (C) 2013 Business Information Systems (Allevo) S.R.L.
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 as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>
17 * or contact Allevo at : 031281 Bucuresti, 23C Calea Vitan, Romania,
18 * phone +40212554577, office@allevo.ro <mailto:office@allevo.ro>, www.allevo.ro.
19 */
20 
21 #ifndef LOCKINGPTR_H
22 #define LOCKINGPTH_H
23 
24 #ifdef WIN32
25  #define __MSXML_LIBRARY_DEFINED__
26  #include <windows.h>
27  #include <string.h>
28 #endif
29 
30 #include <sstream>
31 #include <cstring>
32 #include <cerrno>
33 
34 namespace FinTP
35 {
36  template <typename T>
37  class LockingPtr
38  {
39  public:
40 
41  // Constructors/destructors
42  LockingPtr( volatile T& obj, pthread_mutex_t& mtx ) : pObj_( const_cast< T* >( &obj ) ), pMtx_( &mtx )
43  {
44  int errCode = pthread_mutex_lock( pMtx_ );
45  if ( 0 != errCode )
46  {
47  stringstream errorMessage;
48 #ifdef CRT_SECURE
49  char errBuffer[ 95 ];
50  strerror_s( errBuffer, sizeof( errBuffer ), errCode );
51  errorMessage << "Unable to lock mutex. Error code : " << errCode << " [" << errBuffer << "]";
52 #else
53  errorMessage << "Unable to lock mutex. Error code : " << errCode << " [" << strerror( errCode ) << "]";
54 #endif
55  throw runtime_error( errorMessage.str() );
56  }
57  }
58 
59  LockingPtr( volatile T& obj, volatile pthread_mutex_t& mtx ) : pObj_( const_cast< T* >( &obj ) ),
60  pMtx_( const_cast< pthread_mutex_t* >( &mtx ) )
61  {
62  int errCode = pthread_mutex_lock( pMtx_ );
63  if ( 0 != errCode )
64  {
65  stringstream errorMessage;
66 #ifdef CRT_SECURE
67  char errBuffer[ 95 ];
68  strerror_s( errBuffer, sizeof( errBuffer ), errCode );
69  errorMessage << "Unable to lock mutex. Error code : " << errCode << " [" << errBuffer << "]";
70 #else
71  errorMessage << "Unable to lock mutex. Error code : " << errCode << " [" << strerror( errCode ) << "]";
72 #endif
73  throw runtime_error( errorMessage.str() );
74  }
75  }
76 
78  {
79  int errCode = pthread_mutex_unlock( pMtx_ );
80  if ( 0 != errCode )
81  {
82  stringstream errorMessage;
83 #ifdef CRT_SECURE
84  char errBuffer[ 95 ];
85  strerror_s( errBuffer, sizeof( errBuffer ), errCode );
86  errorMessage << "Unable to unlock mutex. Error code : " << errCode << " [" << errBuffer << "]";
87 #else
88  errorMessage << "Unable to unlock mutex. Error code : " << errCode << " [" << strerror( errCode ) << "]";
89 #endif
90  throw runtime_error( errorMessage.str() );
91  }
92  }
93 
94  // Pointer behavior
95  T& operator*() { return *pObj_; }
96  T* operator->() { return pObj_; }
97 
98  private :
99 
100  T* pObj_;
101  pthread_mutex_t* pMtx_;
102 
103  // disable copying
104  LockingPtr( const LockingPtr& );
105  LockingPtr& operator=( const LockingPtr& );
106  };
107 
108  class UIntType
109  {
110  public :
111 
112  #if defined( AIX ) && defined( DIE_HARD )
113  typedef register UINT32 base_type;
114  #elif defined( WIN32 ) //&& defined( DIE_HARD )
115  typedef volatile LONG base_type;
116  #else
117  typedef volatile unsigned int base_type;
118  #endif
119 
121 
123  {
124  #if defined( AIX ) && defined( DIE_HARD )
125  register unsigned int zeroOffset = 0;
126  register unsigned int temp;
127  asm
128  {
129  retry:
130  lwarx temp, zeroOffset, value // Read integer from RAM into r4, placing reservation.
131  addi temp, temp, 1 // Add 1 to r4.
132  stwcx. temp, zeroOffset, value // Attempt to store incremented value back to RAM.
133  bne- retry // If the store failed (unlikely), retry.
134  }
135  return temp;
136  #elif defined( WIN32 ) //&& defined( DIE_HARD )
137  return InterlockedIncrement( value );
138  #else
139  return ++( *value );
140  #endif
141  }
142 
144  {
145  #if defined( AIX ) && defined( DIE_HARD )
146  register unsigned int zeroOffset = 0;
147  register unsigned int temp;
148 
149  asm
150  {
151  again:
152  lwarx temp, zeroOffset, value
153  subi temp, temp, 1
154  stwcx. temp, zeroOffset, value
155  bne- again
156  }
157  return temp;
158  #elif defined( WIN32 ) //&& defined( DIE_HARD )
159  return InterlockedDecrement( value );
160  #else
161  return --( *value );
162  #endif
163  }
164  };
165 }
166 
167 #endif // LOCKINGPTR_H