1 /*
2     Copyright (c) 2009-2011 250bpm s.r.o.
3     Copyright (c) 2007-2009 iMatix Corporation
4     Copyright (c) 2011 VMware, Inc.
5     Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
6 
7     This file is part of Crossroads I/O project.
8 
9     Crossroads I/O is free software; you can redistribute it and/or modify it
10     under the terms of the GNU Lesser General Public License as published by
11     the Free Software Foundation; either version 3 of the License, or
12     (at your option) any later version.
13 
14     Crossroads is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU Lesser General Public License for more details.
18 
19     You should have received a copy of the GNU Lesser General Public License
20     along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #ifndef __XS_SESSION_BASE_HPP_INCLUDED__
24 #define __XS_SESSION_BASE_HPP_INCLUDED__
25 
26 #include <string>
27 
28 #include "own.hpp"
29 #include "io_object.hpp"
30 #include "pipe.hpp"
31 
32 namespace xs
33 {
34 
35     class pipe_t;
36     class io_thread_t;
37     class socket_base_t;
38     struct i_engine;
39 
40     class session_base_t :
41         public own_t,
42         public io_object_t,
43         public i_pipe_events
44     {
45     public:
46 
47         //  Create a session of the particular type.
48         static session_base_t *create (xs::io_thread_t *io_thread_,
49             bool connect_, xs::socket_base_t *socket_,
50             const options_t &options_, const char *protocol_,
51             const char *address_);
52 
53         //  To be used once only, when creating the session.
54         void attach_pipe (xs::pipe_t *pipe_);
55 
56         //  Following functions are the interface exposed towards the engine.
57         //  They can be overloaded by specific session types to intercept
58         //  events coming from the engine.
59         virtual int read (msg_t *msg_);
60         virtual int write (msg_t *msg_);
61         virtual void flush ();
62         virtual void detach ();
63 
64         //  i_pipe_events interface implementation.
65         void read_activated (xs::pipe_t *pipe_);
66         void write_activated (xs::pipe_t *pipe_);
67         void hiccuped (xs::pipe_t *pipe_);
68         void terminated (xs::pipe_t *pipe_);
69 
70     protected:
71 
72         session_base_t (xs::io_thread_t *io_thread_, bool connect_,
73             xs::socket_base_t *socket_, const options_t &options_,
74             const char *protocol_, const char *address_);
75         ~session_base_t ();
76 
77     private:
78 
79         void start_connecting (bool wait_);
80 
81         void detached ();
82 
83         //  Handlers for incoming commands.
84         void process_plug ();
85         void process_attach (xs::i_engine *engine_);
86         void process_term (int linger_);
87 
88         //  i_poll_events handlers.
89         void timer_event (handle_t handle_);
90 
91         //  Remove any half processed messages. Flush unflushed messages.
92         //  Call this function when engine disconnect to get rid of leftovers.
93         void clean_pipes ();
94 
95         //  Call this function to move on with the delayed process_term.
96         void proceed_with_term ();
97 
98         //  If true, this session (re)connects to the peer. Otherwise, it's
99         //  a transient session created by the listener.
100         bool connect;
101 
102         //  Pipe connecting the session to its socket.
103         xs::pipe_t *pipe;
104 
105         //  This flag is true if the remainder of the message being processed
106         //  is still in the in pipe.
107         bool incomplete_in;
108 
109         //  True if termination have been suspended to push the pending
110         //  messages to the network.
111         bool pending;
112 
113         //  The protocol I/O engine connected to the session.
114         xs::i_engine *engine;
115 
116         //  The socket the session belongs to.
117         xs::socket_base_t *socket;
118 
119         //  I/O thread the session is living in. It will be used to plug in
120         //  the engines into the same thread.
121         xs::io_thread_t *io_thread;
122 
123         //  If true, identity is to be sent to the network.
124         bool send_identity;
125 
126         //  If true, identity was already sent to the current connection.
127         bool identity_sent;
128 
129         //  If true, identity is to be received from the network.
130         bool recv_identity;
131 
132         //  If true, identity was already received from the current connection.
133         bool identity_recvd;
134 
135         //  Protocol and address to use when connecting.
136         std::string protocol;
137         std::string address;
138 
139         //  Handle of the linger timer, if active, NULL otherwise.
140         handle_t linger_timer;
141 
142         session_base_t (const session_base_t&);
143         const session_base_t &operator = (const session_base_t&);
144     };
145 
146 }
147 
148 #endif
149