tunnel_context.h

Go to the documentation of this file.
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

Generated on Wed Jan 28 21:37:59 2009 for sigx++ by  doxygen 1.5.8