thread_pos.hpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Ifdefs
10 *****************************************************************************/
11 
12 #ifndef ECL_THREADS_THREAD_POS_HPP_
13 #define ECL_THREADS_THREAD_POS_HPP_
14 
15 /*****************************************************************************
16 ** Platform Check
17 *****************************************************************************/
18 
19 #include <ecl/config/ecl.hpp>
20 #if defined(ECL_IS_POSIX)
21 
22 /*****************************************************************************
23 ** Includes
24 *****************************************************************************/
25 
26 #include <pthread.h>
28 #include <ecl/config/macros.hpp>
31 #include <ecl/utilities/void.hpp>
33 #include "priority_pos.hpp"
34 
35 /*****************************************************************************
36 ** Namespaces
37 *****************************************************************************/
38 
39 namespace ecl {
40 namespace threads {
41 
42 /*****************************************************************************
43 ** Interface [ThreadTask]
44 *****************************************************************************/
51 class ECL_LOCAL ThreadTaskBase {
52 public:
53  virtual ~ThreadTaskBase() {};
54 
55 protected:
56  ThreadTaskBase(const Priority& priority) : priority_level(priority) {};
57  ecl::Priority priority_level;
58 };
68 template <typename F, bool IsReferenceWrapper = false>
69 class ECL_LOCAL ThreadTask : public ThreadTaskBase {
70 public:
79  ThreadTask(const F &f, const Priority &priority) : ThreadTaskBase(priority), function(f) {
81  };
82  virtual ~ThreadTask() {};
94  static void* EntryPoint(void *ptr_this) {
95  ThreadTask< F, false > *ptr = static_cast< ThreadTask< F, false > * >(ptr_this);
96  ecl::set_priority(ptr->priority_level);
97  (ptr->function)();
98  delete ptr;
99  ptr_this = NULL;
100  return ptr_this;
101  }
102 
103 private:
104  F function;
105 };
106 
116 template <typename F>
117 class ECL_LOCAL ThreadTask<F, true> : public ThreadTaskBase {
118 public:
127  ThreadTask(const F &f, const Priority &priority) : ThreadTaskBase(priority), function(f.reference()) {
129  };
130  virtual ~ThreadTask() {};
142  static void* EntryPoint(void *ptr_this) {
143  ThreadTask< F, true > *ptr = static_cast< ThreadTask< F, true > * >(ptr_this);
144  ecl::set_priority(ptr->priority_level);
145  (ptr->function)();
146  delete ptr;
147  ptr_this = NULL;
148  return ptr_this;
149  }
150 
151 private:
152  typename F::type &function;
153 };
154 
155 }; // namespace threads
156 
157 /*****************************************************************************
158 ** Interface [Thread]
159 *****************************************************************************/
233 class ECL_PUBLIC Thread {
234 public:
242  Thread() :
243  thread_task(NULL),
244  has_started(false),
245  join_requested(false)
246  {}
266  Thread(VoidFunction function, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
276  Error start(VoidFunction function, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
300  template <typename C>
301  Thread(void (C::*function)(), C &c, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
312  template <typename C>
313  Error start(void (C::*function)(), C &c, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
314 
353  template <typename F>
354  Thread(const F &function, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
364  template <typename F>
365  Error start(const F &function, const Priority &priority = DefaultPriority, const long &stack_size = -1 );
366 
375  virtual ~Thread();
376 
382  bool isRunning() const { if ( thread_task == NULL ) { return false; } else { return true; } }
383 
402  void cancel();
403 
411  void join();
412 
413 
414 private:
415  pthread_t thread_handle;
416  pthread_attr_t attrs;
417  sched_param schedule_parameters;
418  threads::ThreadTaskBase *thread_task;
419  bool has_started;
420  bool join_requested;
421 
422  void initialise(const long &stack_size);
423 
424  enum ThreadProperties {
425  DefaultStackSize = -1
426  };
427 };
428 
429 /*****************************************************************************
430 ** Template Implementation [Thread]
431 *****************************************************************************/
432 
433 template <typename C>
434 Thread::Thread(void (C::*function)(), C &c, const Priority &priority, const long &stack_size) :
435  thread_task(NULL),
436  has_started(false),
437  join_requested(false)
438 {
439  start<C>(function, c, priority, stack_size);
440 
441 }
442 
443 template <typename F>
444 Thread::Thread(const F &function, const Priority &priority, const long &stack_size) :
445  thread_task(NULL),
446  has_started(false),
447  join_requested(false)
448 {
449  start<F>(function, priority, stack_size);
450 }
451 
452 template <typename C>
453 Error Thread::start(void (C::*function)(), C &c, const Priority &priority, const long &stack_size)
454 {
455  if ( has_started ) {
456  ecl_debug_throw(StandardException(LOC,BusyError,"The thread has already been started."));
457  return Error(BusyError); // if in release mode, gracefully fall back to return values.
458  } else {
459  has_started = true;
460  }
461  initialise(stack_size);
462  thread_task = new threads::ThreadTask< BoundNullaryMemberFunction<C,void> >(generateFunctionObject( function, c ), priority);
463  int result = pthread_create(&(this->thread_handle), &(this->attrs), threads::ThreadTask< BoundNullaryMemberFunction<C,void> >::EntryPoint, thread_task);
464  pthread_attr_destroy(&attrs);
465  if ( result != 0 ) {
466  delete thread_task;
467  thread_task = NULL;
468  ecl_debug_throw(threads::throwPthreadCreateException(LOC,result));
469  return threads::handlePthreadCreateError(result); // if in release mode, gracefully fall back to return values.
470  }
471  return Error(NoError);
472 }
473 
474 template <typename F>
475 Error Thread::start(const F &function, const Priority &priority, const long &stack_size)
476 {
477  if ( has_started ) {
478  ecl_debug_throw(StandardException(LOC,BusyError,"The thread has already been started."));
479  return Error(BusyError); // if in release mode, gracefully fall back to return values.
480  } else {
481  has_started = true;
482  }
483  initialise(stack_size);
484  thread_task = new threads::ThreadTask<F, is_reference_wrapper<F>::value >(function, priority);
485  int result = pthread_create(&(this->thread_handle), &(this->attrs), threads::ThreadTask<F, is_reference_wrapper<F>::value>::EntryPoint, thread_task);
486  pthread_attr_destroy(&attrs);
487  if ( result != 0 ) {
488  delete thread_task;
489  thread_task = NULL;
490  ecl_debug_throw(threads::throwPthreadCreateException(LOC,result));
491  return threads::handlePthreadCreateError(result); // if in release mode, gracefully fall back to return values.
492  }
493  return Error(NoError);
494 }
495 
496 }; // namespace ecl
497 
498 #endif /* ECL_IS_POSIX */
499 #endif /* ECL_THREADS_THREAD_POS_HPP_ */
void f()
Embedded control libraries.
Exception handlers for pthreads.
void(* VoidFunction)()
#define ecl_compile_time_concept_check(Model)
#define ecl_debug_throw(exception)
Posix priority scheduling.
NullaryFreeFunction< R > generateFunctionObject(R(*function)())
#define ECL_LOCAL
#define ECL_PUBLIC
Priority
Shared abstraction of the scheduling priorities.


ecl_threads
Author(s): Daniel Stonier
autogenerated on Mon Feb 28 2022 22:18:53