CPN
Computational Process Networks
PthreadLib.cc
Go to the documentation of this file.
1 //=============================================================================
2 // Pthread class
3 //-----------------------------------------------------------------------------
4 // POSIX Pthread class library
5 // Copyright (C) 1997-1999 The University of Texas
6 //
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published
9 // by the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Library General Public License for more details.
16 //
17 // The GNU Public License is available in the file LICENSE, or you
18 // can write to the Free Software Foundation, Inc., 59 Temple Place -
19 // Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
20 // World Wide Web at http://www.fsf.org.
21 //=============================================================================
22 
23 #ifdef EXTERNAL_TEMPLATES
24 # pragma implementation "PthreadLib.h"
25 #endif
26 
28 #ifdef _POSIX_THREADS
29 
30 
31 //-----------------------------------------------------------------------------
33 //-----------------------------------------------------------------------------
34 {
36  returnResult = 0;
37  inJoin = false;
39  TrapError( pthread_create( &theThread, 0, PthreadEntryPoint, this) );
40  state = created;
41  cond.Broadcast();
42 }
43 
44 
45 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
48 {
50  returnResult = 0;
51  inJoin = false;
53 
54  // It should simply be:
55 // TrapError( pthread_create(&theThread, attr, PthreadEntryPoint, this) );
56 
57  // This is necessary because
58  // SGI's pthread_create is not const correct!!!
59  pthread_attr_t* myAttr = (PthreadAttr&)attr;
60  TrapError( pthread_create(&theThread, myAttr, PthreadEntryPoint, this) );
61  state = created;
62  cond.Broadcast();
63 }
64 
65 
66 //-----------------------------------------------------------------------------
68 //-----------------------------------------------------------------------------
69 {
70  try {
71  // Force the thread to terminate if it has not already done so.
72  // Is it safe to do this to a thread that has already terminated?
73 
74  bool need_start = false;
75  {
77  switch (state) {
78  case uninitialized:
79  // should be impossible
80  return;
81  case created:
82  need_start = true;
83  case started:
84  case running:
85  state = canceled;
86  cond.Broadcast();
87  default:
88  break;
89  }
90  }
91 
92  if (need_start) { Start(); }
93  // Now wait.
94  Join();
95  } catch (...) {
96  std::terminate();
97  }
98 }
99 
100 void Pthread::Start(void) {
102  if (state == created) {
103  state = started;
104  cond.Broadcast();
105  }
106 }
107 
108 void *Pthread::Join(void) {
109  void *result = 0;
110  {
112  if (inJoin || state == joined) {
113  while (state != joined) {
114  cond.Wait(mutex);
115  }
116  return returnResult;
117  }
118  inJoin = true;
119  }
120  TrapError( pthread_join(theThread, &result) );
121  {
123  returnResult = result;
124  state = joined;
125  cond.Broadcast();
126  return returnResult;
127  }
128 }
129 
130 //-----------------------------------------------------------------------------
132 //-----------------------------------------------------------------------------
133 {
134  void* result = 0;
135  Pthread* ptr = (Pthread*) arg;
136  {
138  while (ptr->state == created) {
139  ptr->cond.Wait(ptr->mutex);
140  }
141  if (ptr->state != started) return 0;
142  ptr->state = running;
143  ptr->cond.Broadcast();
144  }
145  TestCancel();
146  pthread_cleanup_push( PthreadCleanup, ptr);
147  result = ptr->EntryPoint();
148  pthread_cleanup_pop(1);
149  return result;
150 }
151 
152 
153 //-----------------------------------------------------------------------------
154 void Pthread::PthreadCleanup(void* arg)
155 //-----------------------------------------------------------------------------
156 {
157  Pthread* ptr = (Pthread*) arg;
159 // ptr->Cleanup(); // the sub-classes have already been destructed
160  ptr->state = done;
161  ptr->cond.Broadcast();
162 }
163 
164 
165 #endif
PthreadCondition & Wait(PthreadMutex &mutex)
static void * PthreadEntryPoint(void *arg)
Definition: PthreadLib.cc:131
Pthread(void)
Definition: PthreadLib.cc:32
PthreadCondition & Broadcast(void)
static void PthreadCleanup(void *arg)
Definition: PthreadLib.cc:154
PthreadCondition cond
Definition: PthreadLib.h:85
virtual ~Pthread(void)
Definition: PthreadLib.cc:67
PthreadState state
Definition: PthreadLib.h:90
static void TestCancel(void)
Definition: PthreadBase.h:63
PthreadMutex mutex
Definition: PthreadLib.h:84
void * Join(void)
Definition: PthreadLib.cc:108
void * returnResult
Definition: PthreadLib.h:86
bool inJoin
Definition: PthreadLib.h:87
void TrapError(int result)
pthread_t theThread
Definition: PthreadBase.h:126
virtual void * EntryPoint(void)=0
void Start(void)
Definition: PthreadLib.cc:100