This file is indexed.

/usr/include/sigx-2.0/sigx/signal_wrapper_base.h is in libsigx-2.0-dev 2.0.2-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef _SIGX_SIGNAL_BASE_HPP_
#define _SIGX_SIGNAL_BASE_HPP_

/*
 * Copyright 2006 Klaus Triendl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free 
 * Software Foundation, 51 Franklin Street, Fifth Floor, 
 * Boston, MA 02110-1301, USA.
*/

#include <tr1/memory>
#include <utility> // std::pair
#include <sigxconfig.h>
#include <sigx/fwddecl.h>
#include <sigx/static_assert.h>
#include <sigx/nonheapallocatable.h>
#include <sigx/shared_dispatchable.h>
#include <sigx/connection_wrapper.h>
#include <sigx/auto_tunneler.h>


namespace sigx
{

/**	@short The base for a sigx::signal_wrapper.
 *	
 *	It holds a shared_dispatchable and a shared signal source.
 *	
 *	@ingroup signals
 */
class SIGX_API signal_wrapper_base: nonheapallocatable
{

protected:
	/**	
	 *	@throw	Might throw a std::bad_alloc exception (from dispatchable's ctor)
	 */
	signal_wrapper_base();
	// non-virtual by design
	~signal_wrapper_base() throw();
	signal_wrapper_base(const shared_dispatchable& _A_disp, const std::tr1::shared_ptr<signal_source_base>& _A_sigsource) throw();

	// implicit copy ctor is fine
	// implicit assignment operator is fine



	/**	@short	Prepare a shared sigc::connection pointer and a connection_wrapper.
	 *	
	 *	The sigc::connection itself will be created in the context of the server thread
	 */
	std::pair<connection_wrapper, std::tr1::shared_ptr<sigc_connection_ptr> >
	prepare_connection(const tunnel_base& _A_tunnel) const;

	/**	@short	Call _A_func_conn_handler in the context of the server thread, _A_func_conn_handler 
	 *			resolves to typed_connection_handler<>::connect[_notify] connecting _A_func to the server 
	 *			thread's signal
	 */
	template<typename T_functor, typename T_functor_conn_handler>
	connection_wrapper connect(const T_functor& _A_func, const T_functor_conn_handler& _A_func_conn_handler) const;

protected:
	///	The server thread's shared dispatchable to operate on for making connections or 
	///	emitting the signal
	shared_dispatchable m_disp;
	///	The source for the server thread's signal
	std::tr1::shared_ptr<signal_source_base> m_sigsource;
};


template<typename T_functor, typename T_functor_conn_handler>
connection_wrapper signal_wrapper_base::connect(const T_functor& _A_func, const T_functor_conn_handler& _A_func_conn_handler) const
{
	typedef internal::auto_tunneler<T_functor> auto_tunneler_t;
	
	// passed in functor must not be a slot or adapt a slot;
	// we have to apply this restriction because slots might have bound
	// trackables that can cause non-threadsafe access to the passed in slot
	// which will live in the context of the server thread
	SIGX_STATIC_ASSERT((sigx::internal::is_or_adapts_slot<T_functor>::value == false));
	
	// toplevel functor must be a tunnel functor
	SIGX_STATIC_ASSERT((sigc::is_base_and_derived<tunnel_base, typename auto_tunneler_t::functor_type>::value == true));

	typename auto_tunneler_t::functor_type functor2connect = 
		auto_tunneler_t::auto_open_tunnel(_A_func);
	// the validity of tunnel functors doesn't get tracked by the sigc++ default visit_each mechanism, 
	// we activate sigx' own validity tracking, which is threadsafe
	functor2connect.activate_validity_tracking();

	const std::pair<connection_wrapper, std::tr1::shared_ptr<sigc_connection_ptr> >& ret = 
		signal_wrapper_base::prepare_connection(functor2connect);

	try
	{
		// now send a message to the server thread (holding the signal the client thread wants 
		// to connect to);
		// the message gets handled by a special function handling the connection
		open_tunnel_with(
			_A_func_conn_handler, 
			m_disp
		)
		// transfer:
		// - the prepared connection pointer
		// - the signal source
		// - the functor to connect
		// 
		// The functor to connect is the tunnel functor wrapped in an exception catcher
		// that catches a bad_dispatcher error.
		// This is necessary because the dispatcher of the tunnel functor (that is 
		// probably the dispatcher running in the context of the calling thread)
		// could go out of scope (e.g. because the calling thread finishes), but 
		// the tunnel functor is still connected to the server thread's signal.
		// Before the server thread gets the disconnect message (which is 
		// triggered by the dispatcher or by trackable objects of the calling 
		// thread going out of scope) it might emit the signal 
		// on this tunnel functor and gets a bad_dispatcher error thrown.
		// Because the programmer can't really influence this situation, sigx
		// catches the exception.
		(	ret.second, m_sigsource, 
			sigc::exception_catch(functor2connect, 
				// use a catcher here because the signal might get emitted 
				// while the dispatcher the tunnel functor operates on dies
				// before the tunnel functor is disconnected from that signal
				// (btw: this is done internally by the validity trackable
				bad_dispatcher_catcher<typename auto_tunneler_t::functor_type::result_type>()
			)
		);
	}
	catch (...)
	{
		// message dispatching failed at the call site;
		// reset pointer to the sigc connection to make the connection invalid
		*ret.second = 0;
		throw;
	}

	return ret.first;
}


} // namespace sigx


#endif // end file guard