1 /*
2 * SObjectizer-5
3 */
4
5 /*!
6 * \file
7 * \brief Implementation of some parts of handler makers which can't be inline.
8 *
9 * \since
10 * v.5.5.23
11 */
12
13 #include <so_5/handler_makers.hpp>
14
15 #include <so_5/impl/enveloped_msg_details.hpp>
16
17 namespace so_5 {
18
19 namespace details {
20
21 namespace {
22
23 bool
process_envelope_when_handler_found(const msg_type_and_handler_pair_t & handler,message_ref_t & message)24 process_envelope_when_handler_found(
25 const msg_type_and_handler_pair_t & handler,
26 message_ref_t & message )
27 {
28 using namespace so_5::enveloped_msg::impl;
29
30 bool result = false;
31
32 // We don't expect exceptions here and can't restore after them.
33 so_5::details::invoke_noexcept_code( [&] {
34 auto & envelope = message_to_envelope( message );
35
36 mchain_demand_handler_invoker_t invoker{ handler };
37 envelope.access_hook(
38 so_5::enveloped_msg::access_context_t::handler_found,
39 invoker );
40
41 result = invoker.was_handled();
42 } );
43
44 return result;
45 }
46
47 } /* namespace anonymous */
48
49 SO_5_FUNC
50 bool
find_and_use_handler(const msg_type_and_handler_pair_t * left,const msg_type_and_handler_pair_t * right,const std::type_index & msg_type,message_ref_t & message)51 handlers_bunch_basics_t::find_and_use_handler(
52 const msg_type_and_handler_pair_t * left,
53 const msg_type_and_handler_pair_t * right,
54 const std::type_index & msg_type,
55 message_ref_t & message )
56 {
57 bool ret_value = false;
58
59 msg_type_and_handler_pair_t key{ msg_type };
60 auto it = std::lower_bound( left, right, key );
61 if( it != right && it->m_msg_type == key.m_msg_type )
62 {
63 // Handler is found and must be called.
64 switch( message_kind( message ) )
65 {
66 case message_t::kind_t::signal : [[fallthrough]];
67 case message_t::kind_t::classical_message : [[fallthrough]];
68 case message_t::kind_t::user_type_message :
69 // This is an async message.
70 // Simple call is enough.
71 ret_value = true;
72 it->m_handler( message );
73 break;
74
75 case message_t::kind_t::enveloped_msg :
76 // Invocation must be done a special way.
77 ret_value = process_envelope_when_handler_found( *it, message );
78 break;
79 }
80 }
81
82 return ret_value;
83 }
84
85 } /* namespace details */
86
87 } /* namespace so_5 */
88
89