Switch to unified view

a/src/utils/netcon.h b/src/utils/netcon.h
...
...
14
 *   You should have received a copy of the GNU General Public License
14
 *   You should have received a copy of the GNU General Public License
15
 *   along with this program; if not, write to the
15
 *   along with this program; if not, write to the
16
 *   Free Software Foundation, Inc.,
16
 *   Free Software Foundation, Inc.,
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 */
18
 */
19
#include <sys/time.h>
20
#include <map>
19
#include "refcntr.h"
21
#include "refcntr.h"
22
23
using std::map;
20
24
21
/// A set of classes to manage client-server communication over a
25
/// A set of classes to manage client-server communication over a
22
/// connection-oriented network, or a pipe.
26
/// connection-oriented network, or a pipe.
23
///
27
///
24
/// The listening/connection-accepting code currently only uses
28
/// The listening/connection-accepting code currently only uses
...
...
32
/// descriptor)
36
/// descriptor)
33
37
34
/// Base class for all network endpoints:
38
/// Base class for all network endpoints:
35
class Netcon;
39
class Netcon;
36
typedef RefCntr<Netcon> NetconP;
40
typedef RefCntr<Netcon> NetconP;
41
class SelectLoop;
37
42
38
class Netcon {
43
class Netcon {
39
public:
44
public:
40
    enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
45
    enum Event {NETCONPOLL_READ = 0x1, NETCONPOLL_WRITE=0x2};
41
    Netcon() 
46
    Netcon() 
42
    : m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0)
47
    : m_peer(0), m_fd(-1), m_ownfd(true), m_didtimo(0), m_wantedEvents(0),
48
    m_loop(0)
43
    {}
49
    {}
44
    virtual ~Netcon();
50
    virtual ~Netcon();
45
    /// Remember whom we're talking to. We let external code do this because 
51
    /// Remember whom we're talking to. We let external code do this because 
46
    /// the application may have a non-dns method to find the peer name.
52
    /// the application may have a non-dns method to find the peer name.
47
    virtual void setpeer(const char *hostname);
53
    virtual void setpeer(const char *hostname);
...
...
73
    /// Add events to current set
79
    /// Add events to current set
74
    int addselevents(int evs) {return m_wantedEvents |= evs;}
80
    int addselevents(int evs) {return m_wantedEvents |= evs;}
75
    /// Clear events from current set
81
    /// Clear events from current set
76
    int clearselevents(int evs) {return m_wantedEvents &= ~evs;}
82
    int clearselevents(int evs) {return m_wantedEvents &= ~evs;}
77
83
84
    friend class SelectLoop;
85
    SelectLoop *getloop() {return m_loop;}
86
78
    /// Utility function for a simplified select() interface: check one fd
87
    /// Utility function for a simplified select() interface: check one fd
79
    /// for reading or writing, for a specified maximum number of seconds.
88
    /// for reading or writing, for a specified maximum number of seconds.
80
    static int select1(int fd, int secs, int writing = 0);
89
    static int select1(int fd, int secs, int writing = 0);
81
    
90
91
protected:
92
    char *m_peer; // Name of the connected host
93
    int   m_fd;
94
    bool  m_ownfd;
95
    int   m_didtimo;
96
    // Used when part of the selectloop map.
97
    short m_wantedEvents;
98
    SelectLoop *m_loop;
99
    // Method called by the selectloop when something can be done with a netcon
100
    virtual int cando(Netcon::Event reason) = 0;
101
    // Called when added to loop
102
    virtual void setloop(SelectLoop *loop) {m_loop = loop;}
103
};
104
105
82
    /// The selectloop interface is used to implement parallel servers. 
106
/// The selectloop interface is used to implement parallel servers. 
83
    /// All the interface is static (independant of any given object).
107
// The select loop mechanism allows several netcons to be used for io
108
// in a program without blocking as long as there is data to be read
109
// or written. In a multithread program which is also using select, it
110
// would typically make sense to have one SelectLoop active per
111
// thread.
112
class SelectLoop {
113
public:
114
    SelectLoop()
115
  : m_selectloopDoReturn(false), m_selectloopReturnValue(0),
116
    m_placetostart(0), 
117
    m_periodichandler(0), m_periodicparam(0), m_periodicmillis(0)
118
    {}
84
119
85
    /// Loop waiting for events on the connections and call the
120
    /// Loop waiting for events on the connections and call the
86
    /// cando() method on the object when something happens (this will in 
121
    /// cando() method on the object when something happens (this will in 
87
    /// turn typically call the app callback set on the netcon). Possibly
122
    /// turn typically call the app callback set on the netcon). Possibly
88
    /// call the periodic handler (if set) at regular intervals.
123
    /// call the periodic handler (if set) at regular intervals.
89
    /// @return -1 for error. 0 if no descriptors left for i/o. 1 for periodic
124
    /// @return -1 for error. 0 if no descriptors left for i/o. 1 for periodic
90
    ///  timeout (should call back in after processing)
125
    ///  timeout (should call back in after processing)
91
    static  int selectloop();
126
    int doLoop();
127
92
    /// Call from data handler: make selectloop return the param value
128
    /// Call from data handler: make selectloop return the param value
93
    static void selectloopReturn(int value) 
129
    void loopReturn(int value) 
94
    {
130
    {
95
    o_selectloopDoReturn = true;
131
    m_selectloopDoReturn = true;
96
    o_selectloopReturnValue = value;
132
    m_selectloopReturnValue = value;
97
    }
133
    }
98
    /// Add a connection to be monitored (this will usually be called
134
    /// Add a connection to be monitored (this will usually be called
99
    /// from the server's listen connection's accept callback)
135
    /// from the server's listen connection's accept callback)
100
    static  int addselcon(NetconP con, int);
136
    int addselcon(NetconP con, int events);
101
    /// Remove a connection from the monitored set. Note that this is
137
    /// Remove a connection from the monitored set. This is
102
    /// automatically called from the Netcon destructor, and when EOF is
138
    /// automatically called when EOF is detected on a connection.
103
    /// detected on a connection.
104
    static  int remselcon(NetconP con);
139
    int remselcon(NetconP con);
105
140
106
    /// Set a function to be called periodically, or a time before return.
141
    /// Set a function to be called periodically, or a time before return.
107
    /// @param handler the function to be called. 
142
    /// @param handler the function to be called. 
108
    ///  - if it is 0, selectloop() will return after ms mS (and can be called
143
    ///  - if it is 0, selectloop() will return after ms mS (and can be called
109
    ///    again
144
    ///    again
110
    ///  - if it is not 0, it will be called at ms mS intervals. If its return 
145
    ///  - if it is not 0, it will be called at ms mS intervals. If its return 
111
    ///    value is <= 0, selectloop will return. 
146
    ///    value is <= 0, selectloop will return. 
112
    /// @param clp client data to be passed to handler at every call.
147
    /// @param clp client data to be passed to handler at every call.
113
    /// @param ms milliseconds interval between handler calls or
148
    /// @param ms milliseconds interval between handler calls or
114
    ///   before return. Set to 0 for no periodic handler.
149
    ///   before return. Set to 0 for no periodic handler.
115
    static  void setperiodichandler(int (*handler)(void *), void *clp, int ms);
150
    void setperiodichandler(int (*handler)(void *), void *clp, int ms);
116
151
117
protected:
152
private:
153
    // Set by client callback to tell selectloop to return.
118
    static bool o_selectloopDoReturn;
154
    bool m_selectloopDoReturn;
119
    static int  o_selectloopReturnValue;
155
    int  m_selectloopReturnValue;
120
    char *m_peer; // Name of the connected host
156
    int  m_placetostart;
121
    int   m_fd;
122
    bool  m_ownfd;
123
    int   m_didtimo;
124
    // Used when part of the selectloop map.
125
    short m_wantedEvents;
126
    // Method called by the selectloop when something can be done with a netcon
127
    virtual int cando(Netcon::Event reason) = 0;
128
};
129
157
158
    // Map of NetconP indexed by fd
159
    map<int, NetconP> m_polldata;
160
161
    // The last time we did the periodic thing. Initialized by setperiodic()
162
    struct timeval m_lasthdlcall;
163
    // The call back function and its parameter
164
    int (*m_periodichandler)(void *);
165
    void *m_periodicparam;
166
    // The periodic interval
167
    int m_periodicmillis;
168
    void periodictimeout(struct timeval *tv);
169
    int maybecallperiodic();
170
};
130
171
131
///////////////////////
172
///////////////////////
132
class NetconData;
173
class NetconData;
133
174
134
/// Class for the application callback routine (when in
175
/// Class for the application callback routine (when in selectloop). 
176
///
177
/// This is set by the app on the NetconData by calling
178
/// setcallback(). It is then called from the NetconData's cando()
179
/// routine, itself called by selectloop.
180
/// 
135
/// selectloop). It would be nicer to override cando() in a subclass
181
/// It would be nicer to override cando() in a subclass instead of
136
/// instead of setting a callback, but this can't be done conveniently
182
/// setting a callback, but this can't be done conveniently because
137
/// because accept() always creates a base NetconData (another way
183
/// accept() always creates a base NetconData (another approach would
138
/// would be to pass a factory function function to the listener, to create
184
/// be to pass a factory function to the listener, to create
139
/// NetconData derivatives).
185
/// NetconData derived classes).
140
class NetconWorker {
186
class NetconWorker {
141
public:
187
public:
142
    virtual ~NetconWorker() {}
188
    virtual ~NetconWorker() {}
143
    // NetconP holds a NetconData oeuf corse
144
    virtual int data(NetconData *con, Netcon::Event reason) = 0;
189
    virtual int data(NetconData *con, Netcon::Event reason) = 0;
145
};
190
};
146
191
147
/// Base class for connections that actually transfer data. T
192
/// Base class for connections that actually transfer data. T
148
class NetconData : public Netcon {
193
class NetconData : public Netcon {
...
...
183
    char *m_buf;    // Buffer. Only used when doing getline()s
228
    char *m_buf;    // Buffer. Only used when doing getline()s
184
    char *m_bufbase;    // Pointer to current 1st byte of useful data
229
    char *m_bufbase;    // Pointer to current 1st byte of useful data
185
    int m_bufbytes; // Bytes of data.
230
    int m_bufbytes; // Bytes of data.
186
    int m_bufsize;  // Total buffer size
231
    int m_bufsize;  // Total buffer size
187
    RefCntr<NetconWorker> m_user;
232
    RefCntr<NetconWorker> m_user;
188
    virtual int cando(Netcon::Event reason);
233
    virtual int cando(Netcon::Event reason); // Selectloop slot
189
};
234
};
190
235
191
/// Network endpoint, client side.
236
/// Network endpoint, client side.
192
class NetconCli : public NetconData {   
237
class NetconCli : public NetconData {   
193
public:
238
public: