84143278f156dd362e5ce8beae02777580340c19
[senf.git] / senf / Utils / Daemon / Daemon.ih
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Daemon internal header */
25
26 #ifndef IH_SENF_Utils_Daemon_Daemon_
27 #define IH_SENF_Utils_Daemon_Daemon_ 1
28
29 // Custom includes
30 #include <deque>
31 #include <senf/boost_intrusive/iset.hpp>
32 #include <senf/boost_intrusive/iset_hook.hpp>
33 #include <boost/utility.hpp>
34 #include <boost/function.hpp>
35 #include <senf/Scheduler/Scheduler.hh>
36
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 namespace senf {
40 namespace detail {
41
42     /** \brief Internal: Watch daemon process for successful startup */
43     class DaemonWatcher
44         : boost::noncopyable
45     {
46     public:
47
48         DaemonWatcher(int pid, int coutpipe, int cerrpipe, int stdout, int stderr);
49
50         void run();
51
52     private:
53
54         class Forwarder
55         {
56         public:
57             typedef boost::function<void ()> Callback;
58
59             Forwarder(int src, Callback cb);
60             ~Forwarder();
61
62             void addTarget(int fd);
63
64         private:
65
66             // This is awkward ... we'll need to erase an element from the target list given
67             // only the target object. This is best implement using an intrusive container.
68             // However, this makes memory-management explicit and we'll need to be careful.
69             typedef std::deque<char> Buffer;
70             struct TargetListTag;
71             typedef boost::intrusive::ilist_base_hook<TargetListTag> TargetListBase;
72
73             struct Target : public TargetListBase
74             {
75                 Target(Forwarder & fwd, int fd);
76
77                 int fd;
78                 Buffer::size_type offset;
79                 scheduler::FdEvent writeevent;
80             };
81             typedef boost::intrusive::ilist<TargetListBase::value_traits<Target>,false> Targets;
82
83             struct DestroyDelete
84             {
85                 template <class T>
86                 void operator()(T * t) { delete t; }
87             };
88
89             void readData(int event);
90             void writeData(int event, Target * target);
91
92             Buffer buffer_;
93             int src_;
94             Targets targets_;
95             Callback cb_;
96             scheduler::FdEvent readevent_;
97         };
98
99         void pipeClosed(int id);
100         void sigChld(siginfo_t const &);
101         void childDied();
102         void childOk();
103
104         int childPid_;
105         int coutpipe_;
106         int cerrpipe_;
107         int stdout_;
108         int stderr_;
109         bool sigChld_;
110
111         scheduler::SignalEvent cldSignal_;
112         scheduler::TimerEvent timer_;
113         Forwarder coutForwarder_;
114         Forwarder cerrForwarder_;
115     };
116
117 }}
118
119 //-/////////////////////////////////////////////////////////////////////////////////////////////////
120 #endif
121
122 \f
123 // Local Variables:
124 // mode: c++
125 // fill-column: 100
126 // comment-column: 40
127 // c-file-style: "senf"
128 // indent-tabs-mode: nil
129 // ispell-local-dictionary: "american"
130 // compile-command: "scons -u test"
131 // End: