YAMI4 Core
channel_group.h
1 // Copyright Maciej Sobczak 2008-2019.
2 // This file is part of YAMI4.
3 //
4 // YAMI4 is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // YAMI4 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with YAMI4. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef YAMICORE_CHANNEL_GROUP_H_INCLUDED
18 #define YAMICORE_CHANNEL_GROUP_H_INCLUDED
19 
20 #include "channel.h"
21 #include "channel_descriptor.h"
22 #include "core.h"
23 #include "details-fwd.h"
24 #include "options.h"
25 
26 #ifdef YAMI4_WITH_OPEN_SSL
27 #ifdef _WIN32
28 // this is necessary to avoid conflicts between
29 // WinSock2.h (used by YAMI4) and winsock.h (used by OpenSSL):
30 #include <WinSock2.h>
31 #endif // _WIN32
32 #include <openssl/ssl.h>
33 #endif // YAMI4_WITH_OPEN_SSL
34 
35 // selected per platform
36 #include <details-types.h>
37 #include <mutex.h>
38 #include <selector.h>
39 
40 namespace yami
41 {
42 
43 namespace core
44 {
45 
46 class parameters;
47 class serializable;
48 
49 } // namespace core
50 
51 namespace details
52 {
53 
54 class channel_group
55 {
56 public:
57 
58  core::result init(allocator & alloc,
59  const core::parameters * configuration_options,
61  void * dispatch_hint,
62  core::closed_connection_function disconnection_hook,
63  void * disconnection_hook_hint);
64 
65  void install_event_notifications(
66  core::event_notification_function event_notification_callback,
67  void * event_notification_hint);
68 
69  void install_io_error_logger(
70  core::io_error_function io_error_callback,
71  void * io_error_callback_hint);
72 
73  void clean(bool uses_private_area);
74 
75  // opens new channel for the given target
76  // or returns the descriptor of the existing channel
77  core::result open(const char * target,
78  core::channel_descriptor & new_channel,
79  bool & created_new_channel, bool do_lock = true,
80  const core::parameters * overriding_options = NULL);
81 
82  core::result is_open(const char * target,
83  core::channel_descriptor & existing_channel) const;
84 
85  // adds an existing channel to the list, used to add new channels
86  // created by listeners; target's ownership is transfered
87  core::result add_existing(
88  char * target, io_descriptor_type fd, protocol prot,
89  std::size_t preferred_frame_size,
90  core::channel_descriptor & new_descriptor,
91  channel * & new_channel);
92 #ifdef YAMI4_WITH_OPEN_SSL
93  core::result add_existing_ssl(
94  char * target, io_descriptor_type fd, protocol prot,
95  std::size_t preferred_frame_size,
96  core::channel_descriptor & new_descriptor);
97 #endif // YAMI4_WITH_OPEN_SSL
98 
99  // insert a poison pill to the given channel
100  // do nothing if no such channel exists
101  // close immediately and ignore priority if hard_close == true
102  core::result close(core::channel_descriptor cd,
103  bool hard_close, std::size_t priority);
104  core::result close(const char * target,
105  bool hard_close, std::size_t priority);
106 
107  // serializes the new message into frames and injects them
108  // into the output queue of the given channel
109  core::result post(core::channel_descriptor cd,
110  const core::serializable & message_header,
111  const core::serializable & message_body,
112  std::size_t priority,
113  core::message_progress_function progress_callback,
114  void * progress_hint);
115  core::result post(const char * target,
116  const core::serializable & message_header,
117  const core::serializable & message_body,
118  std::size_t priority,
119  core::message_progress_function progress_callback,
120  void * progress_hint);
121 
122  core::result add_listener(const char * target,
124  void * connection_hook_hint,
125  const char * * resolved_target);
126  void remove_listener(const char * target);
127 
128  // waits for the readiness of any dependent channel
129  // to perform I/O work and executing a unit of work
130  // (the unit of work can involve many channels, if more than one
131  // is ready for transmission; it can also return without
132  // physically doing any I/O-related work)
133  // the timeout is in milliseconds,
134  // 0 means immediate check and action (non-blocking)
135  core::result do_some_work(std::size_t timeout,
136  bool allow_outgoing_traffic,
137  bool allow_incoming_traffic);
138 
139  // used to inject already received frames (UDP),
140  // should be called from synchronized context
141  core::result process_complete_incoming_frame(core::channel_descriptor cd,
142  const char * buffer, const std::size_t buffer_size);
143 
144 #ifdef YAMI4_WITH_QNX
145  // used to establish the channel id for receiving responses
146  // from remote peers, this id is sent together with each outgoing message;
147  // only the first created QNX listener is remembered
148  void set_default_qnx_listening_channel_id(int chid);
149 #endif // YAMI4_WITH_QNX
150 
151  core::result interrupt_work_waiter();
152 
153  const options & get_options() const { return configuration_options_; }
154 
155  void get_channel_usage(int & max_allowed, int & used);
156 
157  core::result get_pending_outgoing_bytes(core::channel_descriptor cd, std::size_t & bytes);
158  core::result get_pending_outgoing_bytes(const char * target, std::size_t & bytes);
159 
160 private:
161 
162  channel_group(const channel_group &);
163  void operator=(const channel_group &);
164 
165  core::result do_close(channel * ch, std::size_t priority,
166  std::size_t index);
167  core::result do_hard_close(channel * ch, std::size_t index);
168 
169  // finds existing channel with the given target name
170  // returns ok or no_such_name
171  core::result find_existing_channel(const char * target,
172  std::size_t & index, std::size_t & sequence_number,
173  channel * & ch) const;
174 
175  // finds an empty slot or makes room for new empty slot
176  // reservation means that the empty slot will not be found
177  // the second time until it is filled and cleared for reuse
178  // returns ok or no_memory
179  core::result find_unused_channel(std::size_t & index, bool reserve);
180 
181  bool channel_dec_ref(std::size_t index, channel * ch);
182 
183  void prune_listeners();
184 
185  std::size_t generate_message_id();
186 
187  mutable mutex mtx_;
188 
189  options configuration_options_;
190 
191  channel_holder * channel_holders_;
192  std::size_t channels_num_;
193  channel * * shadow_channels_;
194  std::size_t shadow_channels_num_;
195 
196  listener * first_listener_;
197 
198 #ifdef YAMI4_WITH_QNX
199  int qnx_listener_channel_id_;
200 #endif // YAMI4_WITH_QNX
201 
202  selector selector_;
203 
204  allocator * alloc_;
205 
206  bool closing_;
207 
208  std::size_t last_message_id_;
209 
210  core::incoming_message_dispatch_function incoming_message_callback_;
211  void * incoming_message_hint_;
212  core::closed_connection_function disconnection_hook_;
213  void * disconnection_hook_hint_;
214 
215  core::event_notification_function event_notification_callback_;
216  void * event_notification_hint_;
217 
218  core::io_error_function io_error_callback_;
219  void * io_error_callback_hint_;
220 
221 #ifdef YAMI4_WITH_OPEN_SSL
222  SSL_CTX * ssl_ctx_;
223 #endif // YAMI4_WITH_OPEN_SSL
224 };
225 
226 } // namespace details
227 
228 } // namespace yami
229 
230 #endif // YAMICORE_CHANNEL_GROUP_H_INCLUDED
void(* closed_connection_function)(void *hint, const char *name, result reason)
Definition: core.h:103
void(* io_error_function)(void *hint, int error_code, const char *description)
Type of function callback for internal I/O error logging.
Definition: core.h:149
void(* message_progress_function)(void *hint, std::size_t sent_bytes, std::size_t total_byte_count)
Definition: core.h:121
void(* new_incoming_connection_function)(void *hint, const char *source, std::size_t index, std::size_t sequence_number)
Definition: core.h:90
Namespace devoted for everything related to YAMI4.
Definition: agent.h:25
void(* incoming_message_dispatch_function)(void *hint, const char *source, const char *header_buffers[], std::size_t header_buffer_sizes[], std::size_t num_of_header_buffers, const char *body_buffers[], std::size_t body_buffer_sizes[], std::size_t num_of_body_buffers)
Definition: core.h:70
void(* event_notification_function)(void *hint, event_notification e, const char *str, std::size_t size)
Definition: core.h:142
result
General type for reporting success and error states.
Definition: core.h:32