Daemon.ih
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief Daemon internal header */
16 
17 #ifndef IH_SENF_Utils_Daemon_Daemon_
18 #define IH_SENF_Utils_Daemon_Daemon_ 1
19 
20 // Custom includes
21 #include <deque>
22 #include <boost/intrusive/list.hpp>
23 #include <boost/intrusive/list_hook.hpp>
24 #include <boost/noncopyable.hpp>
25 #include <boost/function.hpp>
26 #include <senf/Scheduler/Scheduler.hh>
27 
28 //-/////////////////////////////////////////////////////////////////////////////////////////////////
29 
30 namespace senf {
31 namespace detail {
32 
33  /** \brief Internal: Watch daemon process for successful startup */
34  class DaemonWatcher
35  : boost::noncopyable
36  {
37  public:
38 
39  DaemonWatcher(int pid, int coutpipe, int cerrpipe, int stdout, int stderr);
40 
41  void run();
42 
43  private:
44 
45  class Forwarder
46  {
47  public:
48  typedef boost::function<void ()> Callback;
49 
50  Forwarder(int src, Callback cb);
51  ~Forwarder();
52 
53  void addTarget(int fd);
54 
55  private:
56 
57  // This is awkward ... we'll need to erase an element from the target list given
58  // only the target object. This is best implement using an intrusive container.
59  // However, this makes memory-management explicit and we'll need to be careful.
60  typedef std::deque<char> Buffer;
61  struct TargetListTag;
62  typedef boost::intrusive::list_base_hook< boost::intrusive::tag<TargetListTag> > TargetListBase;
63 
64  struct Target : public TargetListBase
65  {
66  Target(Forwarder & fwd, int fd);
67 
68  int fd;
69  Buffer::size_type offset;
70  scheduler::FdEvent writeevent;
71  };
72 
73  typedef boost::intrusive::list< Target,
74  boost::intrusive::constant_time_size<false>,
75  boost::intrusive::base_hook<TargetListBase> > Targets;
76 
77  struct DestroyDelete
78  {
79  template <class T>
80  void operator()(T * t) { delete t; }
81  };
82 
83  void readData(int event);
84  void writeData(int event, Target * target);
85 
86  Buffer buffer_;
87  int src_;
88  Targets targets_;
89  Callback cb_;
90  scheduler::FdEvent readevent_;
91  };
92 
93  void pipeClosed(int id);
94  void sigChld(siginfo_t const &);
95  void childDied();
96  void childOk();
97 
98  int childPid_;
99  int coutpipe_;
100  int cerrpipe_;
101  int stdout_;
102  int stderr_;
103  bool sigChld_;
104 
105  scheduler::SignalEvent cldSignal_;
106  scheduler::TimerEvent timer_;
107  Forwarder coutForwarder_;
108  Forwarder cerrForwarder_;
109  };
110 
111 }}
112 
113 //-/////////////////////////////////////////////////////////////////////////////////////////////////
114 #endif
115 
116 
117 // Local Variables:
118 // mode: c++
119 // fill-column: 100
120 // comment-column: 40
121 // c-file-style: "senf"
122 // indent-tabs-mode: nil
123 // ispell-local-dictionary: "american"
124 // compile-command: "scons -u test"
125 // End: