Skip to content

Commit 1775b1d

Browse files
issue #14
* new thread_group class to handle abstract_threads * new abstract_thread (probably safer).
1 parent 260a954 commit 1775b1d

File tree

5 files changed

+129
-95
lines changed

5 files changed

+129
-95
lines changed

cpp-pthread.xcodeproj/project.pbxproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,10 @@
286286
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
287287
GCC_WARN_UNUSED_FUNCTION = YES;
288288
GCC_WARN_UNUSED_VARIABLE = YES;
289-
HEADER_SEARCH_PATHS = "$(SRCROOT)/include";
289+
HEADER_SEARCH_PATHS = (
290+
"$(SRCROOT)/include",
291+
"$(SRCROOT)/../include",
292+
);
290293
MACOSX_DEPLOYMENT_TARGET = 10.11;
291294
MTL_ENABLE_DEBUG_INFO = YES;
292295
ONLY_ACTIVE_ARCH = YES;
@@ -325,7 +328,10 @@
325328
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
326329
GCC_WARN_UNUSED_FUNCTION = YES;
327330
GCC_WARN_UNUSED_VARIABLE = YES;
328-
HEADER_SEARCH_PATHS = "$(SRCROOT)/include";
331+
HEADER_SEARCH_PATHS = (
332+
"$(SRCROOT)/include",
333+
"$(SRCROOT)/../include",
334+
);
329335
MACOSX_DEPLOYMENT_TARGET = 10.11;
330336
MTL_ENABLE_DEBUG_INFO = NO;
331337
SDKROOT = macosx;
@@ -369,6 +375,7 @@
369375
E5B044101CAE7342005C89BB /* Release */,
370376
);
371377
defaultConfigurationIsVisible = 0;
378+
defaultConfigurationName = Release;
372379
};
373380
E5EC5B6C1C9C2C3000E21131 /* Build configuration list for PBXProject "cpp-pthread" */ = {
374381
isa = XCConfigurationList;

include/ibm.hpp

Lines changed: 0 additions & 46 deletions
This file was deleted.

include/pthread/thread.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <string>
1414
#include <functional>
1515
#include <memory>
16+
#include <list>
1617

1718
#include "pthread/config.h"
1819

@@ -151,6 +152,52 @@ namespace pthread {
151152
thread_status _status;
152153
};
153154

155+
class abstract_thread: public runnable {
156+
public:
157+
virtual ~abstract_thread();
158+
159+
void start();
160+
161+
int join() { return _thread->join() ;};
162+
163+
private:
164+
pthread::thread *_thread;
165+
};
166+
167+
/** group (list) of abstract_threads.
168+
*
169+
* method in this class apply's to all threads in the group. this means that when an thread_group instance is deallocated, all threads it references are deleted.
170+
*/
171+
class thread_group{
172+
public:
173+
/** Setup a thread container/list.
174+
*
175+
* @param destructor_joins_first if true then destructor tries to join all regsitered threads before deleting thread instances.
176+
*/
177+
thread_group( bool destructor_joins_first = false ) __NOEXCEPT__;
178+
179+
/** delete all threads referenced by the thread_group.
180+
*/
181+
virtual ~thread_group();
182+
183+
/** @param add/register a thread to the group.
184+
*/
185+
void add(abstract_thread *thread);
186+
187+
/** start run all registered threads.
188+
* @see add(abstract_thread *thread)
189+
*/
190+
void start();
191+
192+
/** what for all threads to join the caller of this method.
193+
*/
194+
void join();
195+
196+
private:
197+
std::list<pthread::abstract_thread*> _threads;
198+
bool _destructor_joins_first;
199+
};
200+
154201
// exception & errors --------
155202

156203
class thread_exception: public pthread_exception {

src/thread.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,11 @@ namespace pthread {
5555
return rc;
5656
}
5757

58-
#ifdef __IBMCPP__
5958
thread::thread(): _status(thread_status::not_a_thread), _thread(0){
60-
#else
61-
thread::thread(): _status{thread_status::not_a_thread}, _thread{nullptr}{
62-
#endif
6359

6460
}
6561

66-
#ifdef __IBMCPP__
6762
thread::thread (const runnable &work): thread(){
68-
#else
69-
thread::thread (const runnable &work): thread{}{
70-
#endif
7163
int rc = 0 ;
7264
pthread_attr_t attr;
7365

@@ -109,9 +101,50 @@ namespace pthread {
109101
}
110102

111103
thread::~thread () {
112-
// if ( _status == thread_status::a_thread ){
113-
// pthread_attr_destroy(&_attr);
114-
// }
104+
}
105+
106+
abstract_thread::~abstract_thread(){
107+
108+
delete _thread;
109+
}
110+
111+
void abstract_thread::start(){
112+
113+
_thread = new pthread::thread(*this);
114+
}
115+
116+
thread_group::thread_group(bool destructor_joins_first ) __NOEXCEPT__: _destructor_joins_first(destructor_joins_first){
117+
118+
}
119+
120+
thread_group::~thread_group(){
121+
while(! _threads.empty()){
122+
std::auto_ptr<pthread::abstract_thread> pat(_threads.front());
123+
_threads.pop_front();
124+
125+
if ( _destructor_joins_first ){
126+
try {
127+
pat->join();
128+
} catch ( ... ){};
129+
}
130+
}
131+
}
132+
133+
void thread_group::add(pthread::abstract_thread *thread){
134+
135+
_threads.push_back(thread);
136+
}
137+
138+
void thread_group::start(){
139+
for(auto iterator = _threads.begin(); iterator != _threads.end(); iterator++){
140+
(*iterator)->start();
141+
}
142+
}
143+
144+
void thread_group::join(){
145+
for(auto iterator = _threads.begin(); iterator != _threads.end(); iterator++){
146+
(*iterator)->join();
147+
}
115148
}
116149

117150
/**
@@ -128,11 +161,7 @@ namespace pthread {
128161

129162
// exception -------
130163

131-
#ifdef __IBMCPP__
132164
thread_exception::thread_exception(const string message, const int pthread_error): pthread_exception(message, pthread_error){
133-
#else
134-
thread_exception::thread_exception(const string message, const int pthread_error): pthread_exception{message, pthread_error}{
135-
#endif
136165
}
137166

138167
} // namespace pthread

tests/without-cpp11-pthread-tests.cpp

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void message ( const std::string m){
2525
std::cout << m << std::endl;
2626
}
2727

28-
class worker: public pthread::runnable {
28+
class worker: public pthread::abstract_thread {
2929
public:
3030

3131
worker(const std::string m = "anonymous worker", int sleep = 2*1000): msg(m), _sleep(sleep){
@@ -37,7 +37,7 @@ class worker: public pthread::runnable {
3737
};
3838

3939
void run() __NOEXCEPT__ __OVERRIDE__ {
40-
40+
message("worker: " + msg);
4141
{
4242
pthread::lock_guard<pthread::mutex> lck(mtx);
4343

@@ -67,40 +67,37 @@ class worker: public pthread::runnable {
6767
int main(int argc, const char * argv[]) {
6868

6969
pthread::string dummy;
70-
worker w("laura");
71-
pthread::thread t0;
72-
pthread::thread t2(w);
73-
t0 = ibm::move(t2) ;
74-
t0.join();
7570

76-
std::auto_ptr<pthread::thread> pt0(new pthread::thread(w));
77-
pt0->join();
78-
79-
// std::list<std::auto_ptr<pthread::thread>> threads;
80-
std::list<pthread::thread> threads;
81-
for (auto x = 20 ; x > 0 ; x--){
82-
// threads.push_back(std::auto_ptr<pthread::thread>(new pthread::thread(w)));
83-
threads.push_back(ibm::move(pthread::thread(w)));
71+
{
72+
worker w1("herbert", 2);
73+
w1.start();
74+
w1.join();
8475
}
85-
// threads.push_back(pthread::thread(w));
86-
// threads.push_back(pthread::thread(w));
87-
// threads.push_back(pthread::thread(w));
88-
// threads.push_back(pthread::thread(worker("herbert's worker")));
76+
// worker w("laura");
77+
// pthread::thread t0;
78+
// pthread::thread t2(w);
79+
// t0 = ibm::move(t2) ;
80+
// t0.join();
8981
//
90-
// message("increment counter");
91-
// for ( auto x = 20000 ; x > 0 ; x--){
92-
// pthread::lock_guard<pthread::mutex> lck(mtx);
93-
// counter++ ;
94-
// condition.notify_one();
95-
// }
96-
// message("main is waiting for threads to finish");
97-
//
98-
// std::list<std::auto_ptr<pthread::thread>>::iterator iterator;
99-
// for(iterator = threads.begin(); iterator != threads.end(); iterator++){
100-
// message("join a thread (loop)");
101-
// (*iterator)->join();
102-
// }
82+
// std::auto_ptr<pthread::thread> pt0(new pthread::thread(worker("laura")));
83+
// pt0->join();
10384

85+
pthread::thread_group threads(true);
86+
for (auto x = 10 ; x > 0 ; x--){
87+
threads.add( new worker("herbert"));
88+
}
89+
90+
threads.start();
91+
92+
message("main increment counter");
93+
for ( auto x = 20000 ; x > 0 ; x--){
94+
pthread::lock_guard<pthread::mutex> lck(mtx);
95+
counter++ ;
96+
}
97+
condition.notify_all();
98+
99+
// message("main is waiting for threads to finish");
100+
// threads.join();
104101
message( "end reached");
105102

106103
}

0 commit comments

Comments
 (0)