sigx++ 2.0.1
|
00001 #ifndef _SIGX_TUNNEL_CONTEXT_H_ 00002 #define _SIGX_TUNNEL_CONTEXT_H_ 00003 00004 /* 00005 * Copyright 2007 Klaus Triendl 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Library General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public 00018 * License along with this library; if not, write to the Free 00019 * Software Foundation, 51 Franklin Street, Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include <memory> // std::auto_ptr 00024 #include <sigc++/type_traits.h> 00025 #include <sigc++/adaptors/bound_argument.h> 00026 #include <sigx/fwddecl.h> 00027 #include <sigx/types.h> 00028 #include <sigx/internal_types.h> 00029 #include <sigx/dispatcher.h> 00030 #include <sigx/tunnel_context_base.h> 00031 00032 00033 namespace sigx 00034 { 00035 00044 template<sync_type I_sync, typename T_return, typename T_unary_functor> 00045 struct tunnel_context; 00046 00047 00050 template<sync_type I_sync, typename T_return, typename T_adaptor> 00051 tunnel_context<I_sync, T_return, T_adaptor>* make_new_tunnel_context(const shared_dispatchable& _A_disp, const tunnel_validity_tracker& _A_validity_tracker, const T_adaptor& _A_func) 00052 { 00053 return new tunnel_context<I_sync, T_return, T_adaptor>(_A_disp, _A_validity_tracker, _A_func); 00054 } 00055 00056 00066 template<typename T_return, typename T_unary_functor> 00067 struct tunnel_context<ASYNC, T_return, T_unary_functor>: public tunnel_context_base 00068 { 00069 typedef tunnel_context<ASYNC, T_return, T_unary_functor> this_type; 00070 typedef T_return result_type; 00071 00072 tunnel_context(const shared_dispatchable& _A_disp, const tunnel_validity_tracker& _A_validity_tracker, typename sigc::type_trait<T_unary_functor>::take _A_func): 00073 tunnel_context_base(_A_disp, _A_validity_tracker), 00074 m_boundmessage(_A_func) 00075 {} 00076 00080 result_type tunnel() 00081 { 00082 tunnel_context_base::dispatch_me(); 00083 return result_type(); 00084 } 00085 00086 void invoke() 00087 { 00088 // async tunnels must delete themselves after dispatching 00089 const std::auto_ptr<this_type> autodelete_this(this); 00090 00091 // call functor in the context of the server thread, disregard return value 00092 m_boundmessage(); 00093 } 00094 00095 private: 00096 T_unary_functor m_boundmessage; 00097 }; 00098 00099 00111 template<typename T_return, typename T_unary_functor> 00112 struct tunnel_context<SYNC, T_return, T_unary_functor>: public sync_tunnel_context_base 00113 { 00114 typedef tunnel_context<SYNC, T_return, T_unary_functor> this_type; 00115 typedef T_return result_type; 00116 00117 tunnel_context(const shared_dispatchable& _A_disp, const tunnel_validity_tracker& _A_validity_tracker, typename sigc::type_trait<T_unary_functor>::take _A_func): 00118 sync_tunnel_context_base(_A_disp, _A_validity_tracker), 00119 m_boundmessage(_A_func), 00120 m_bound_result(result_type()) 00121 {} 00122 00126 T_return tunnel() 00127 { 00128 const std::auto_ptr<this_type> autodelete_this(this); 00129 00130 Glib::Mutex::Lock lock(m_mutex); 00131 // rather call tunnel_context_base::dispatch_me() than 00132 // sync_tunnel_context_base::dispatch_me() because we want to ensure 00133 // that the result is returned while we still hold the lock 00134 tunnel_context_base::dispatch_me(); 00135 // synchronize with other end of the tunnel 00136 m_cond.wait(m_mutex); 00137 00138 return m_bound_result.invoke(); 00139 } 00140 00141 void invoke() 00142 { 00143 Glib::Mutex::Lock lock(m_mutex); 00144 // save result 00145 m_bound_result = m_boundmessage(); 00146 00147 // tell the one end of the tunnel that we are done 00148 m_cond.signal(); 00149 } 00150 00151 private: 00152 T_unary_functor m_boundmessage; 00153 sigc::bound_argument<typename sigc::type_trait<T_return>::type> m_bound_result; 00154 }; 00155 00156 00168 template<typename T_unary_functor> 00169 struct tunnel_context<SYNC, void, T_unary_functor>: public sync_tunnel_context_base 00170 { 00171 typedef tunnel_context<SYNC, void, T_unary_functor> this_type; 00172 typedef void result_type; 00173 00174 tunnel_context(const shared_dispatchable& _A_disp, const tunnel_validity_tracker& _A_validity_tracker, typename sigc::type_trait<T_unary_functor>::take _A_func): 00175 sync_tunnel_context_base(_A_disp, _A_validity_tracker), 00176 m_boundmessage(_A_func) 00177 {} 00178 00182 void tunnel() 00183 { 00184 const std::auto_ptr<this_type> autodelete_this(this); 00185 00186 sync_tunnel_context_base::dispatch_me(); 00187 } 00188 00189 void invoke() 00190 { 00191 Glib::Mutex::Lock lock(m_mutex); 00192 m_boundmessage(); 00193 00194 // tell the one end of the tunnel that we are done 00195 m_cond.signal(); 00196 } 00197 00198 private: 00199 T_unary_functor m_boundmessage; 00200 }; 00201 00202 00203 } // namespace sigx 00204 00205 00206 #endif // file guard