Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laeThreadAsync.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // File: laeThreadAsync.cxx
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2015-10-19 10:38:52 -0600 (Mon, 19 Oct 2015) $
10  * $Rev: 4153 $
11  *
12  * \brief Laelaps asynchronous thread class implementation.
13  *
14  * \author Robin Knight (robin.knight@roadnarrows.com)
15  *
16  * \par Copyright
17  * \h_copy 2015-2018. RoadNarrows LLC.\n
18  * http://www.roadnarrows.com\n
19  * All Rights Reserved
20  */
21 /*
22  * @EulaBegin@
23  *
24  * Unless otherwise stated explicitly, all materials contained are copyrighted
25  * and may not be used without RoadNarrows LLC's written consent,
26  * except as provided in these terms and conditions or in the copyright
27  * notice (documents and software) or other proprietary notice provided with
28  * the relevant materials.
29  *
30  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
31  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
32  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
33  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
34  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
35  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
38  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
39  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
40  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
41  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
42  *
43  * @EulaEnd@
44  */
45 ////////////////////////////////////////////////////////////////////////////////
46 
47 #include <sys/types.h>
48 #include <sys/time.h>
49 #include <time.h>
50 #include <pthread.h>
51 
52 #include <string>
53 
54 #include "rnr/rnrconfig.h"
55 #include "rnr/log.h"
56 
57 #include "Laelaps/laelaps.h"
58 #include "Laelaps/laeUtils.h"
59 
60 #include "Laelaps/laeThread.h"
61 #include "Laelaps/laeThreadAsync.h"
62 
63 using namespace std;
64 using namespace laelaps;
65 
66 //------------------------------------------------------------------------------
67 // LaeAsyncJob Class
68 //------------------------------------------------------------------------------
69 
70 LaeAsyncJob::LaeAsyncJob(const string strJobName) : m_strJobName(strJobName)
71 {
73  m_bIsDone = false;
74  m_nJobRc = LAE_OK;
75 }
76 
78 {
79 }
80 
82 {
84 }
85 
87 {
89 }
90 
92 {
94 
95  return m_nJobRc;
96 }
97 
99 {
101  m_bIsDone = true;
102 }
103 
104 void LaeAsyncJob::abort(int rc)
105 {
107  m_bIsDone = true;
108  m_nJobRc = rc;
109 }
110 
111 
112 //------------------------------------------------------------------------------
113 // LaeThreadAsync Class
114 //------------------------------------------------------------------------------
115 
116 const double LaeThreadAsync::ThreadAsyncPrioDft = 25;
117 const double LaeThreadAsync::ThreadAsyncHzDft = 1.0;
118 const char* const LaeThreadAsync::ThreadAsyncNameDft = "Async";
119 
121 {
122  m_pJob = NULL;
123 }
124 
126 {
127  if( m_pJob != NULL )
128  {
129  if( !m_pJob->isDone() )
130  {
131  m_pJob->abort();
132  }
133  }
134 }
135 
136 int LaeThreadAsync::createThread(LaeAsyncJob *pJob, int nPriority)
137 {
138  int rc;
139 
140  if( m_pJob == NULL )
141  {
142  LOGERROR("Creating %s thread with no job.", m_strThreadName.c_str());
143  return -LAE_ECODE_BAD_OP;
144  }
145 
146  m_pJob = pJob;
148 
149  if( (rc = LaeThread::createThread(nPriority)) != LAE_OK )
150  {
151  m_pJob->abort(rc);
153  }
154 
155  return rc;
156 }
157 
158 int LaeThreadAsync::runThread(const double fHz)
159 {
160  if( m_pJob == NULL )
161  {
162  LOGERROR("Running %s thread with no job.", m_strThreadName.c_str());
163  return -LAE_ECODE_BAD_OP;
164  }
165 
166  return LaeThread::runThread(fHz);
167 }
168 
170 {
171  int rc;
172 
173  if( m_pJob != NULL )
174  {
175  if( !m_pJob->isDone() )
176  {
177  m_pJob->abort();
178  }
179  }
180 
182 
184 
185  return rc;
186 }
187 
189 {
190  if( m_pJob != NULL )
191  {
192  m_pJob->getReady();
193  }
194 }
195 
197 {
198  if( m_pJob != NULL )
199  {
200  m_pJob->start();
201  }
202 }
203 
205 {
206  int rc;
207 
208  //
209  // No job, the thread should not be running.
210  //
211  if( m_pJob == NULL )
212  {
214  }
215 
216  //
217  // Run (a slice) of the job.
218  //
219  rc = m_pJob->run();
220 
221  //
222  // Failure - abort.
223  //
224  if( rc < 0 )
225  {
226  m_pJob->abort(rc);
228  }
229 
230  //
231  // Normal completion - terminate.
232  //
233  else if( m_pJob->isDone() )
234  {
235  m_pJob->terminate();
237  }
238 }
239 
241 {
242  if( m_pJob != NULL )
243  {
244  if( !m_pJob->isDone() )
245  {
246  m_pJob->abort();
247  }
248  }
249 
251 }
virtual int terminateThread()
Terminate the thread.
Laelaps thread base class interface.
static const int LAE_ECODE_NO_EXEC
cannot execute error
Definition: laelaps.h:85
virtual int terminateThread()
Terminate the thread.
Definition: laeThread.cxx:202
virtual int runThread(const double fHz=ThreadAsyncHzDft)
Run the thread.
virtual void transToRunning()
Ready to Running state transition function.
virtual ~LaeAsyncJob()
Destructor.
bool isDone()
Test if job has completed or should be aborted.
std::string m_strThreadName
thread identifying name
Definition: laeThread.h:196
virtual void abort(int rc=-LAE_ECODE_INTR)
Abort the job.
virtual void transToExit()
Any to Exit state transition function.
virtual void start()
Start.
LaeThreadAsync()
Default constructor.
virtual void exec()
Execute asynchronous task within scheduled cycle.
thread exiting/exited
Definition: laeThread.h:99
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
virtual void getReady()
Get ready to run.
JobState m_eJobState
job state
int m_nJobRc
job return code
Laelaps common utilities.
Asynchronous job base class.
virtual ~LaeThreadAsync()
Destructor.
virtual int createThread(int nPriority)
Create the thread.
Definition: laeThread.cxx:107
static const int LAE_ECODE_BAD_OP
invalid operation error
Definition: laelaps.h:80
job attached to thread and ready to run
virtual void terminate()
Terminate the job normally.
static const double ThreadAsyncPrioDft
default priority
LaeAsyncJob * m_pJob
attached asynchronous job - owned by caller
Laelaps asynchronouse thread class interface.
virtual void transToReady()
Uninitialized to Ready state transition function.
job created, but not attached to thread
virtual int createThread(LaeAsyncJob *pJob, int nPriority=ThreadAsyncPrioDft)
Create the thread.
virtual int runThread(const double fHz)
Run the thread.
Definition: laeThread.cxx:174
static const double ThreadAsyncHzDft
default run rate
std::string getJobName()
Get the name of the job.
static const char *const ThreadAsyncNameDft
default name
void changeState(ThreadState eNewState)
Change the thread state.
Definition: laeThread.cxx:244
virtual int run()
Run the job.
bool m_bIsDone
job is [not] done
Top-level package include file.
static const int LAE_OK
not an error, success
Definition: laelaps.h:71