forked from solidoss/solidframe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscheduler.hpp
102 lines (80 loc) · 2.46 KB
/
scheduler.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// solid/frame/scheduler.hpp
//
// Copyright (c) 2014 Valentin Palade (vipalade @ gmail . com)
//
// This file is part of SolidFrame framework.
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.
//
#ifndef SOLID_FRAME_SCHEDULER_HPP
#define SOLID_FRAME_SCHEDULER_HPP
#include "solid/utility/dynamicpointer.hpp"
#include "solid/frame/manager.hpp"
#include "solid/frame/schedulerbase.hpp"
namespace solid{
namespace frame{
class Service;
template <class R>
class Scheduler: private SchedulerBase{
public:
typedef typename R::ObjectT ObjectT;
typedef DynamicPointer<ObjectT> ObjectPointerT;
private:
typedef R ReactorT;
struct Worker{
static void run(SchedulerBase *_psched, const size_t _idx){
ReactorT reactor(*_psched, _idx);
if(!reactor.prepareThread(reactor.start())){
return;
}
reactor.run();
reactor.unprepareThread();
}
static bool create(SchedulerBase &_rsched, const size_t _idx, std::thread &_rthr){
bool rv = false;
try{
_rthr = std::thread(Worker::run, &_rsched, _idx);
rv = true;
}catch(...){
}
return rv;
}
};
struct ScheduleCommand{
ObjectPointerT &robjptr;
Service &rsvc;
Event &&revt;
ScheduleCommand(ObjectPointerT &_robjptr, Service &_rsvc, Event &&_revt):robjptr(_robjptr), rsvc(_rsvc), revt(std::move(_revt)){}
bool operator()(ReactorBase &_rreactor){
return static_cast<ReactorT&>(_rreactor).push(robjptr, rsvc, std::move(revt));
}
};
public:
Scheduler(){}
ErrorConditionT start(const size_t _reactorcnt = 1){
ThreadEnterFunctionT enf;
ThreadExitFunctionT exf;
return SchedulerBase::doStart(Worker::create, enf, exf, _reactorcnt);
}
template <class EnterFct, class ExitFct>
ErrorConditionT start(EnterFct _enf, ExitFct _exf, const size_t _reactorcnt = 1){
ThreadEnterFunctionT enf(_enf);
ThreadExitFunctionT exf(_exf);//we don't want to copy _exf
return SchedulerBase::doStart(Worker::create, enf, exf, _reactorcnt);
}
void stop(const bool _wait = true){
SchedulerBase::doStop(_wait);
}
ObjectIdT startObject(
ObjectPointerT &_robjptr, Service &_rsvc,
Event &&_revt, ErrorConditionT &_rerr
){
ScheduleCommand cmd(_robjptr, _rsvc, std::move(_revt));
ScheduleFunctionT fct([&cmd](ReactorBase &_rreactor){return cmd(_rreactor);});
return doStartObject(*_robjptr, _rsvc, fct, _rerr);
}
};
}//namespace frame
}//namespace solid
#endif