switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Daemon / Daemon.ih
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Daemon internal header */
30
31 #ifndef IH_SENF_Utils_Daemon_Daemon_
32 #define IH_SENF_Utils_Daemon_Daemon_ 1
33
34 // Custom includes
35 #include <deque>
36 #include <senf/boost_intrusive/iset.hpp>
37 #include <senf/boost_intrusive/iset_hook.hpp>
38 #include <boost/utility.hpp>
39 #include <boost/function.hpp>
40 #include <senf/Scheduler/Scheduler.hh>
41
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43
44 namespace senf {
45 namespace detail {
46
47     /** \brief Internal: Watch daemon process for successful startup */
48     class DaemonWatcher
49         : boost::noncopyable
50     {
51     public:
52
53         DaemonWatcher(int pid, int coutpipe, int cerrpipe, int stdout, int stderr);
54
55         void run();
56
57     private:
58
59         class Forwarder
60         {
61         public:
62             typedef boost::function<void ()> Callback;
63
64             Forwarder(int src, Callback cb);
65             ~Forwarder();
66
67             void addTarget(int fd);
68
69         private:
70
71             // This is awkward ... we'll need to erase an element from the target list given
72             // only the target object. This is best implement using an intrusive container.
73             // However, this makes memory-management explicit and we'll need to be careful.
74             typedef std::deque<char> Buffer;
75             struct TargetListTag;
76             typedef boost::intrusive::ilist_base_hook<TargetListTag> TargetListBase;
77
78             struct Target : public TargetListBase
79             {
80                 Target(Forwarder & fwd, int fd);
81
82                 int fd;
83                 Buffer::size_type offset;
84                 scheduler::FdEvent writeevent;
85             };
86             typedef boost::intrusive::ilist<TargetListBase::value_traits<Target>,false> Targets;
87
88             struct DestroyDelete
89             {
90                 template <class T>
91                 void operator()(T * t) { delete t; }
92             };
93
94             void readData(int event);
95             void writeData(int event, Target * target);
96
97             Buffer buffer_;
98             int src_;
99             Targets targets_;
100             Callback cb_;
101             scheduler::FdEvent readevent_;
102         };
103
104         void pipeClosed(int id);
105         void sigChld(siginfo_t const &);
106         void childDied();
107         void childOk();
108
109         int childPid_;
110         int coutpipe_;
111         int cerrpipe_;
112         int stdout_;
113         int stderr_;
114         bool sigChld_;
115
116         scheduler::SignalEvent cldSignal_;
117         scheduler::TimerEvent timer_;
118         Forwarder coutForwarder_;
119         Forwarder cerrForwarder_;
120     };
121
122 }}
123
124 //-/////////////////////////////////////////////////////////////////////////////////////////////////
125 #endif
126
127 \f
128 // Local Variables:
129 // mode: c++
130 // fill-column: 100
131 // comment-column: 40
132 // c-file-style: "senf"
133 // indent-tabs-mode: nil
134 // ispell-local-dictionary: "american"
135 // compile-command: "scons -u test"
136 // End: