All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Thread.cpp
Go to the documentation of this file.
1 /*
2  * ThreadBase.cpp
3  *
4  * This file is part of the HausmiSEP project
5  *
6  * Copyright (C) 2012, 2013 Marco Alvarado (malvcr@gmail.com)
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <HSEP/Thread.h>
23 
24 #include <system_error>
25 #include <iostream>
26 #include <unistd.h> /*< for the sleep method */
27 
28 using namespace std;
29 namespace HSEP {
30 
31  /*
32  * This construction was required prior to C++ 11, and it is
33  * a direct requirement from the POSIX standard.
34  *
35  * Has been replaced by a Lambda function.
36  *
37  void threadFunction(void* pThread) {
38  ((Thread*)pThread)->run();
39  }
40  */
41 
42  inline void Thread::run() {
43 
44  bool vContinue;
45  bool vMoving;
46 
47  if (prepare()) {
48  do {
49  {
50  ExclusiveScope vScope((Mutex*)&aMutex);
51  vContinue = aFlags.aContinue;
52  vMoving = aFlags.aMoving;
53  }
54  if (vContinue) {
55  if (vMoving) {
56  string vPackagedState;
57  d_packState(vPackagedState);
58  if (d_sendToDestination(vPackagedState)) {
59  finish();
60  }
61  }
62  else {
63  aExitCode = perform();
64  }
65  }
66  }
67  while (vContinue);
68  dispose();
69  }
70  } // ThreadBase::run
71 
72  bool Thread::dispatch() {
73 
74  bool vDone = false;
75 
76  if (!aFlags.aDispatched) {
77 
78  //
79  // The old POSIX construction is replaced by a
80  // direct in context Lambda function
81  //
82  // aHandler = thread(threadFunction,this);
83  //
84  int vAttempts = 0;
85 
86  while (!vDone && (10 > vAttempts)) {
87 
88  try {
89  aHandler = thread(
90  [&](void* xThreadPtr) {
91  ((Thread*)xThreadPtr)->run();
92  },
93  this
94  );
95  vDone = true;
96  aFlags.aDispatched = true;
97  }
98  // The code 11 represents that the resource is
99  // temporarily unavailable, so the thread must
100  // wait to have enough resources to work
101  //
102  catch (system_error& vException) {
103  error_code vCode = vException.code();
104  if (11 == vCode.value()) {
105  usleep(10);
106  vAttempts++;
107  }
108  }
109  }
110  if (!vDone) {
111  aExitCode = NON_DISPATCHED;
112  }
113  }
114 
115  return vDone;
116 
117  } // Thread::dispatch
118 
119  int Thread::join() {
120 
121  if (aFlags.aDispatched) {
122  aHandler.join();
123  }
124  return aExitCode;
125  } // Thread::join
126 
127  void Thread::relocate(string pDestination) {
128 
129  {
130  ExclusiveScope vScope(&aMutex);
131  aFlags.aMoving = true;
132  }
133 
134  } // Thread::relocate
135 
136 } // HSEP namespace
137 
138 
139 
140