1 #include <boost/statechart/event_processor.hpp>
2 #include <boost/statechart/event.hpp>
4 #include <boost/statechart/fifo_scheduler.hpp>
11 #include <timerlist.h>
17 namespace sc = boost::statechart;
19 #define BOOST_STATECHART_USE_NATIVE_RTTI
20 //#define USE_FIFO_SCHEDULER
21 #ifdef USE_FIFO_SCHEDULER
22 typedef sc::fifo_scheduler<> Scheduler;
25 typedef sc::event_processor< Scheduler > processor_base_type;
26 typedef boost::intrusive_ptr< const sc::event_base > event_ptr_type;
27 struct processor_queue {
28 processor_base_type *processor_;
29 std::deque<event_ptr_type> event_queue_;
30 TimerList timer_list_;
31 const char* state_name;
34 typedef processor_queue *processor_handle;
36 class processor_context {
37 processor_context(Scheduler & scheduler, const processor_handle & handle) :
38 scheduler_( scheduler ),
42 Scheduler & my_scheduler() const { return scheduler_; }
43 const processor_handle & my_handle() const { return handle_; }
45 Scheduler & scheduler_;
46 const processor_handle handle_;
48 friend class sc::event_processor< Scheduler >;
49 friend class Scheduler;
52 Scheduler() : terminated_(false) {
53 pthread_mutex_init(& queue_lock, NULL);
54 sem_init(&waiting_sem, 0, 0);
57 template<class Processor>
58 processor_handle create_processor() {
59 processor_queue *my_processor = new processor_queue();
60 printf("Processor creation.\n");
61 processor_handle handle = my_processor;
62 Processor *p = new Processor( processor_context(*this, (my_processor)) );
63 my_processor->processor_ = p;
64 processor_queue_list.push_back(my_processor);
65 actual_processor = processor_queue_list.back();
71 sem_post(&waiting_sem);
74 void queue_event(const processor_handle & processor, const event_ptr_type & pEvent) {
76 processor->event_queue_.push_back(pEvent);
77 sem_post(&waiting_sem);
83 for(unsigned i = 0; i<processor_queue_list.size();i++) processor_queue_list[i]->processor_->initiate();
84 while (!terminated_) {
85 sem_getvalue(&waiting_sem,&sem_val);
88 ret = sem_timedwait(&waiting_sem, &(actual_timer->ts));
91 ret = sem_wait(&waiting_sem);
94 else ret = sem_wait(&waiting_sem);
98 __fsm_timespec_invalidate(&(actual_timer->ts));
99 actual_processor->processor_->process_event(*(actual_timer->ev));
100 break; /* exit switch */
105 perror("wait_for_event");
106 __fsm_timespec_invalidate(&(actual_timer->ts));
111 for(unsigned i = 0; i<processor_queue_list.size();i++) {
112 if(processor_queue_list[i]->event_queue_.size()>0) {
113 actual_processor = processor_queue_list[i];
114 processor_queue_list[i]->processor_->process_event(*(processor_queue_list[i]->event_queue_.front()));
115 printf("stav: %s\n",actual_processor->state_name);
117 processor_queue_list[i]->event_queue_.pop_front();
122 for(unsigned i = 0; i<processor_queue_list.size();i++) {
123 processor_queue_list[i]->processor_->terminate();
124 delete processor_queue_list[i]->processor_;
125 delete processor_queue_list[i];
128 processor_handle getActualHandle() {
129 return actual_processor;
136 for(unsigned i = 0; i<processor_queue_list.size();i++) {
137 if(processor_queue_list[i]->timer_list_.timeouts.size()>0) {
138 if(!timespec_valid(&(processor_queue_list[i]->timer_list_.timeouts.front()->ts))) {
139 processor_queue_list[i]->timer_list_.timeouts.pop_front();
143 if(i == 0 || !(actual_timer)) {
144 actual_timer = processor_queue_list[i]->timer_list_.timeouts.front();
145 actual_processor = processor_queue_list[i];
148 ret = __fsm_timespec_cmp(&(actual_timer->ts), &(processor_queue_list[i]->timer_list_.timeouts.front()->ts));
150 actual_timer = processor_queue_list[i]->timer_list_.timeouts.front();
151 actual_processor = processor_queue_list[i];
157 if(!actual_timer) return false;
160 std::vector<processor_queue *> processor_queue_list;
161 pthread_mutex_t queue_lock;
164 processor_queue *actual_processor;