xref: /aoo4110/main/io/source/acceptor/acc_socket.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_io.hxx"
26*b1cdbd2cSJim Jagielski #include "acceptor.hxx"
27*b1cdbd2cSJim Jagielski 
28*b1cdbd2cSJim Jagielski #include <hash_set>
29*b1cdbd2cSJim Jagielski #include <algorithm>
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/connection/XConnectionBroadcaster.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/connection/ConnectionSetupException.hpp>
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase2.hxx>
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski using namespace ::osl;
38*b1cdbd2cSJim Jagielski using namespace ::rtl;
39*b1cdbd2cSJim Jagielski using namespace ::cppu;
40*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
41*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io;
42*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::connection;
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski namespace io_acceptor {
46*b1cdbd2cSJim Jagielski 	template<class T>
47*b1cdbd2cSJim Jagielski 	struct ReferenceHash
48*b1cdbd2cSJim Jagielski 	{
operator ()io_acceptor::ReferenceHash49*b1cdbd2cSJim Jagielski 		size_t operator () (const ::com::sun::star::uno::Reference<T> & ref) const
50*b1cdbd2cSJim Jagielski         {
51*b1cdbd2cSJim Jagielski 			return (size_t)ref.get();
52*b1cdbd2cSJim Jagielski 		}
53*b1cdbd2cSJim Jagielski 	};
54*b1cdbd2cSJim Jagielski 
55*b1cdbd2cSJim Jagielski 	template<class T>
56*b1cdbd2cSJim Jagielski 	struct ReferenceEqual
57*b1cdbd2cSJim Jagielski 	{
operator ()io_acceptor::ReferenceEqual58*b1cdbd2cSJim Jagielski 		sal_Bool operator () (const ::com::sun::star::uno::Reference<T> & op1,
59*b1cdbd2cSJim Jagielski 							  const ::com::sun::star::uno::Reference<T> & op2) const
60*b1cdbd2cSJim Jagielski         {
61*b1cdbd2cSJim Jagielski 			return op1.get() == op2.get();
62*b1cdbd2cSJim Jagielski 		}
63*b1cdbd2cSJim Jagielski 	};
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski 	typedef ::std::hash_set< ::com::sun::star::uno::Reference< ::com::sun::star::io::XStreamListener>,
67*b1cdbd2cSJim Jagielski                              ReferenceHash< ::com::sun::star::io::XStreamListener>,
68*b1cdbd2cSJim Jagielski                              ReferenceEqual< ::com::sun::star::io::XStreamListener> >
69*b1cdbd2cSJim Jagielski 	        XStreamListener_hash_set;
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski 	class SocketConnection : public ::cppu::WeakImplHelper2<
73*b1cdbd2cSJim Jagielski         ::com::sun::star::connection::XConnection,
74*b1cdbd2cSJim Jagielski 		::com::sun::star::connection::XConnectionBroadcaster>
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski 	{
77*b1cdbd2cSJim Jagielski 	public:
78*b1cdbd2cSJim Jagielski 		SocketConnection( const OUString & sConnectionDescription );
79*b1cdbd2cSJim Jagielski 		~SocketConnection();
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski 		virtual sal_Int32 SAL_CALL read( ::com::sun::star::uno::Sequence< sal_Int8 >& aReadBytes,
82*b1cdbd2cSJim Jagielski 										 sal_Int32 nBytesToRead )
83*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
84*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException);
85*b1cdbd2cSJim Jagielski 		virtual void SAL_CALL write( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData )
86*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
87*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException);
88*b1cdbd2cSJim Jagielski 		virtual void SAL_CALL flush(  ) throw(
89*b1cdbd2cSJim Jagielski 			::com::sun::star::io::IOException,
90*b1cdbd2cSJim Jagielski 			::com::sun::star::uno::RuntimeException);
91*b1cdbd2cSJim Jagielski 		virtual void SAL_CALL close(  )
92*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
93*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException);
94*b1cdbd2cSJim Jagielski 		virtual ::rtl::OUString SAL_CALL getDescription(  )
95*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::uno::RuntimeException);
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski 		// XConnectionBroadcaster
98*b1cdbd2cSJim Jagielski 		virtual void SAL_CALL addStreamListener(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStreamListener>& aListener)
99*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::uno::RuntimeException);
100*b1cdbd2cSJim Jagielski 		virtual void SAL_CALL removeStreamListener(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStreamListener>& aListener)
101*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::uno::RuntimeException);
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski 	public:
104*b1cdbd2cSJim Jagielski 		void completeConnectionString();
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski 		::osl::StreamSocket m_socket;
107*b1cdbd2cSJim Jagielski 		::osl::SocketAddr m_addr;
108*b1cdbd2cSJim Jagielski 		oslInterlockedCount m_nStatus;
109*b1cdbd2cSJim Jagielski 		::rtl::OUString m_sDescription;
110*b1cdbd2cSJim Jagielski 
111*b1cdbd2cSJim Jagielski 		::osl::Mutex _mutex;
112*b1cdbd2cSJim Jagielski 		sal_Bool     _started;
113*b1cdbd2cSJim Jagielski 		sal_Bool     _closed;
114*b1cdbd2cSJim Jagielski 		sal_Bool     _error;
115*b1cdbd2cSJim Jagielski 		XStreamListener_hash_set _listeners;
116*b1cdbd2cSJim Jagielski 	};
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski 	template<class T>
notifyListeners(SocketConnection * pCon,sal_Bool * notified,T t)119*b1cdbd2cSJim Jagielski 	void notifyListeners(SocketConnection * pCon, sal_Bool * notified, T t)
120*b1cdbd2cSJim Jagielski 	{
121*b1cdbd2cSJim Jagielski   		XStreamListener_hash_set listeners;
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski 		{
124*b1cdbd2cSJim Jagielski 			::osl::MutexGuard guard(pCon->_mutex);
125*b1cdbd2cSJim Jagielski 			if(!*notified)
126*b1cdbd2cSJim Jagielski 			{
127*b1cdbd2cSJim Jagielski 				*notified = sal_True;
128*b1cdbd2cSJim Jagielski 				listeners = pCon->_listeners;
129*b1cdbd2cSJim Jagielski 			}
130*b1cdbd2cSJim Jagielski 		}
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski 		::std::for_each(listeners.begin(), listeners.end(), t);
133*b1cdbd2cSJim Jagielski 	}
134*b1cdbd2cSJim Jagielski 
callStarted(Reference<XStreamListener> xStreamListener)135*b1cdbd2cSJim Jagielski 	static void callStarted(Reference<XStreamListener> xStreamListener)
136*b1cdbd2cSJim Jagielski 	{
137*b1cdbd2cSJim Jagielski 		xStreamListener->started();
138*b1cdbd2cSJim Jagielski 	}
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski 	struct callError {
141*b1cdbd2cSJim Jagielski 		const Any & any;
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski 		callError(const Any & any);
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski 		void operator () (Reference<XStreamListener> xStreamListener);
146*b1cdbd2cSJim Jagielski 	};
147*b1cdbd2cSJim Jagielski 
callError(const Any & aAny)148*b1cdbd2cSJim Jagielski 	callError::callError(const Any & aAny)
149*b1cdbd2cSJim Jagielski 		: any(aAny)
150*b1cdbd2cSJim Jagielski 	{
151*b1cdbd2cSJim Jagielski 	}
152*b1cdbd2cSJim Jagielski 
operator ()(Reference<XStreamListener> xStreamListener)153*b1cdbd2cSJim Jagielski 	void callError::operator () (Reference<XStreamListener> xStreamListener)
154*b1cdbd2cSJim Jagielski 	{
155*b1cdbd2cSJim Jagielski 		xStreamListener->error(any);
156*b1cdbd2cSJim Jagielski 	}
157*b1cdbd2cSJim Jagielski 
callClosed(Reference<XStreamListener> xStreamListener)158*b1cdbd2cSJim Jagielski 	static void callClosed(Reference<XStreamListener> xStreamListener)
159*b1cdbd2cSJim Jagielski 	{
160*b1cdbd2cSJim Jagielski 		xStreamListener->closed();
161*b1cdbd2cSJim Jagielski 	}
162*b1cdbd2cSJim Jagielski 
163*b1cdbd2cSJim Jagielski 
SocketConnection(const OUString & sConnectionDescription)164*b1cdbd2cSJim Jagielski 	SocketConnection::SocketConnection( const OUString &sConnectionDescription) :
165*b1cdbd2cSJim Jagielski 		m_nStatus( 0 ),
166*b1cdbd2cSJim Jagielski 		m_sDescription( sConnectionDescription ),
167*b1cdbd2cSJim Jagielski 		_started(sal_False),
168*b1cdbd2cSJim Jagielski 		_closed(sal_False),
169*b1cdbd2cSJim Jagielski 		_error(sal_False)
170*b1cdbd2cSJim Jagielski 	{
171*b1cdbd2cSJim Jagielski 		g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
172*b1cdbd2cSJim Jagielski 		// make it unique
173*b1cdbd2cSJim Jagielski 		m_sDescription += OUString( RTL_CONSTASCII_USTRINGPARAM( ",uniqueValue=" ) );
174*b1cdbd2cSJim Jagielski 		m_sDescription += OUString::valueOf(
175*b1cdbd2cSJim Jagielski             sal::static_int_cast< sal_Int64 >(
176*b1cdbd2cSJim Jagielski                 reinterpret_cast< sal_IntPtr >(&m_socket)),
177*b1cdbd2cSJim Jagielski             10 );
178*b1cdbd2cSJim Jagielski 	}
179*b1cdbd2cSJim Jagielski 
~SocketConnection()180*b1cdbd2cSJim Jagielski 	SocketConnection::~SocketConnection()
181*b1cdbd2cSJim Jagielski 	{
182*b1cdbd2cSJim Jagielski 		g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
183*b1cdbd2cSJim Jagielski 	}
184*b1cdbd2cSJim Jagielski 
completeConnectionString()185*b1cdbd2cSJim Jagielski 	void SocketConnection::completeConnectionString()
186*b1cdbd2cSJim Jagielski 	{
187*b1cdbd2cSJim Jagielski 		OUStringBuffer buf( 256 );
188*b1cdbd2cSJim Jagielski 		buf.appendAscii( ",peerPort=" );
189*b1cdbd2cSJim Jagielski 		buf.append( (sal_Int32) m_socket.getPeerPort() );
190*b1cdbd2cSJim Jagielski 		buf.appendAscii( ",peerHost=" );
191*b1cdbd2cSJim Jagielski 		buf.append( m_socket.getPeerHost( ) );
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski 		buf.appendAscii( ",localPort=" );
194*b1cdbd2cSJim Jagielski 		buf.append( (sal_Int32) m_socket.getLocalPort() );
195*b1cdbd2cSJim Jagielski 		buf.appendAscii( ",localHost=" );
196*b1cdbd2cSJim Jagielski 		buf.append( m_socket.getLocalHost() );
197*b1cdbd2cSJim Jagielski 
198*b1cdbd2cSJim Jagielski 		m_sDescription += buf.makeStringAndClear();
199*b1cdbd2cSJim Jagielski 	}
200*b1cdbd2cSJim Jagielski 
read(Sequence<sal_Int8> & aReadBytes,sal_Int32 nBytesToRead)201*b1cdbd2cSJim Jagielski 	sal_Int32 SocketConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead )
202*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
203*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException)
204*b1cdbd2cSJim Jagielski 	{
205*b1cdbd2cSJim Jagielski 		if( ! m_nStatus )
206*b1cdbd2cSJim Jagielski 		{
207*b1cdbd2cSJim Jagielski 			notifyListeners(this, &_started, callStarted);
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski 			if( aReadBytes.getLength() != nBytesToRead )
210*b1cdbd2cSJim Jagielski 			{
211*b1cdbd2cSJim Jagielski 				aReadBytes.realloc( nBytesToRead );
212*b1cdbd2cSJim Jagielski 			}
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski 			sal_Int32 i = 0;
215*b1cdbd2cSJim Jagielski 			i = m_socket.read( aReadBytes.getArray()  , aReadBytes.getLength() );
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski 			if(i != nBytesToRead)
218*b1cdbd2cSJim Jagielski 			{
219*b1cdbd2cSJim Jagielski 				OUString message(RTL_CONSTASCII_USTRINGPARAM("acc_socket.cxx:SocketConnection::read: error - "));
220*b1cdbd2cSJim Jagielski 				message +=	m_socket.getErrorAsString();
221*b1cdbd2cSJim Jagielski 
222*b1cdbd2cSJim Jagielski 				IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this)));
223*b1cdbd2cSJim Jagielski 
224*b1cdbd2cSJim Jagielski 				Any any;
225*b1cdbd2cSJim Jagielski 				any <<= ioException;
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski 				notifyListeners(this, &_error, callError(any));
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 				throw ioException;
230*b1cdbd2cSJim Jagielski 			}
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski 			return i;
233*b1cdbd2cSJim Jagielski 		}
234*b1cdbd2cSJim Jagielski 		else
235*b1cdbd2cSJim Jagielski 		{
236*b1cdbd2cSJim Jagielski 			OUString message(RTL_CONSTASCII_USTRINGPARAM("acc_socket.cxx:SocketConnection::read: error - connection already closed"));
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski 			IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this)));
239*b1cdbd2cSJim Jagielski 
240*b1cdbd2cSJim Jagielski 			Any any;
241*b1cdbd2cSJim Jagielski 			any <<= ioException;
242*b1cdbd2cSJim Jagielski 
243*b1cdbd2cSJim Jagielski 			notifyListeners(this, &_error, callError(any));
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski 			throw ioException;
246*b1cdbd2cSJim Jagielski 		}
247*b1cdbd2cSJim Jagielski 	}
248*b1cdbd2cSJim Jagielski 
write(const Sequence<sal_Int8> & seq)249*b1cdbd2cSJim Jagielski 	void SocketConnection::write( const Sequence < sal_Int8 > &seq )
250*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
251*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException)
252*b1cdbd2cSJim Jagielski 	{
253*b1cdbd2cSJim Jagielski 		if( ! m_nStatus )
254*b1cdbd2cSJim Jagielski 		{
255*b1cdbd2cSJim Jagielski 			if( m_socket.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() )
256*b1cdbd2cSJim Jagielski 			{
257*b1cdbd2cSJim Jagielski 				OUString message(RTL_CONSTASCII_USTRINGPARAM("acc_socket.cxx:SocketConnection::write: error - "));
258*b1cdbd2cSJim Jagielski 				message += m_socket.getErrorAsString();
259*b1cdbd2cSJim Jagielski 
260*b1cdbd2cSJim Jagielski 				IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this)));
261*b1cdbd2cSJim Jagielski 
262*b1cdbd2cSJim Jagielski 				Any any;
263*b1cdbd2cSJim Jagielski 				any <<= ioException;
264*b1cdbd2cSJim Jagielski 
265*b1cdbd2cSJim Jagielski 				notifyListeners(this, &_error, callError(any));
266*b1cdbd2cSJim Jagielski 
267*b1cdbd2cSJim Jagielski 				throw ioException;
268*b1cdbd2cSJim Jagielski 			}
269*b1cdbd2cSJim Jagielski 		}
270*b1cdbd2cSJim Jagielski 		else
271*b1cdbd2cSJim Jagielski 		{
272*b1cdbd2cSJim Jagielski 			OUString message(RTL_CONSTASCII_USTRINGPARAM("acc_socket.cxx:SocketConnection::write: error - connection already closed"));
273*b1cdbd2cSJim Jagielski 
274*b1cdbd2cSJim Jagielski 			IOException ioException(message, Reference<XInterface>(static_cast<XConnection *>(this)));
275*b1cdbd2cSJim Jagielski 
276*b1cdbd2cSJim Jagielski 			Any any;
277*b1cdbd2cSJim Jagielski 			any <<= ioException;
278*b1cdbd2cSJim Jagielski 
279*b1cdbd2cSJim Jagielski 			notifyListeners(this, &_error, callError(any));
280*b1cdbd2cSJim Jagielski 
281*b1cdbd2cSJim Jagielski 			throw ioException;
282*b1cdbd2cSJim Jagielski 		}
283*b1cdbd2cSJim Jagielski 	}
284*b1cdbd2cSJim Jagielski 
flush()285*b1cdbd2cSJim Jagielski 	void SocketConnection::flush( )
286*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
287*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException)
288*b1cdbd2cSJim Jagielski 	{
289*b1cdbd2cSJim Jagielski 
290*b1cdbd2cSJim Jagielski 	}
291*b1cdbd2cSJim Jagielski 
close()292*b1cdbd2cSJim Jagielski 	void SocketConnection::close()
293*b1cdbd2cSJim Jagielski 			throw(::com::sun::star::io::IOException,
294*b1cdbd2cSJim Jagielski 				  ::com::sun::star::uno::RuntimeException)
295*b1cdbd2cSJim Jagielski 	{
296*b1cdbd2cSJim Jagielski 		// enshure close is called only once
297*b1cdbd2cSJim Jagielski 		if(  1 == osl_incrementInterlockedCount( (&m_nStatus) ) )
298*b1cdbd2cSJim Jagielski 		{
299*b1cdbd2cSJim Jagielski 			m_socket.shutdown();
300*b1cdbd2cSJim Jagielski 			notifyListeners(this, &_closed, callClosed);
301*b1cdbd2cSJim Jagielski 		}
302*b1cdbd2cSJim Jagielski 	}
303*b1cdbd2cSJim Jagielski 
getDescription()304*b1cdbd2cSJim Jagielski 	OUString SocketConnection::getDescription()
305*b1cdbd2cSJim Jagielski 			throw( ::com::sun::star::uno::RuntimeException)
306*b1cdbd2cSJim Jagielski 	{
307*b1cdbd2cSJim Jagielski 		return m_sDescription;
308*b1cdbd2cSJim Jagielski 	}
309*b1cdbd2cSJim Jagielski 
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski 	// XConnectionBroadcaster
addStreamListener(const Reference<XStreamListener> & aListener)312*b1cdbd2cSJim Jagielski 	void SAL_CALL SocketConnection::addStreamListener(const Reference<XStreamListener> & aListener) throw(RuntimeException)
313*b1cdbd2cSJim Jagielski 	{
314*b1cdbd2cSJim Jagielski 		MutexGuard guard(_mutex);
315*b1cdbd2cSJim Jagielski 
316*b1cdbd2cSJim Jagielski 		_listeners.insert(aListener);
317*b1cdbd2cSJim Jagielski 	}
318*b1cdbd2cSJim Jagielski 
removeStreamListener(const Reference<XStreamListener> & aListener)319*b1cdbd2cSJim Jagielski 	void SAL_CALL SocketConnection::removeStreamListener(const Reference<XStreamListener> & aListener) throw(RuntimeException)
320*b1cdbd2cSJim Jagielski 	{
321*b1cdbd2cSJim Jagielski 		MutexGuard guard(_mutex);
322*b1cdbd2cSJim Jagielski 
323*b1cdbd2cSJim Jagielski 		_listeners.erase(aListener);
324*b1cdbd2cSJim Jagielski 	}
325*b1cdbd2cSJim Jagielski 
SocketAcceptor(const OUString & sSocketName,sal_uInt16 nPort,sal_Bool bTcpNoDelay,const OUString & sConnectionDescription)326*b1cdbd2cSJim Jagielski 	SocketAcceptor::SocketAcceptor( const OUString &sSocketName,
327*b1cdbd2cSJim Jagielski 									sal_uInt16 nPort,
328*b1cdbd2cSJim Jagielski 									sal_Bool bTcpNoDelay,
329*b1cdbd2cSJim Jagielski 									const OUString &sConnectionDescription) :
330*b1cdbd2cSJim Jagielski 		m_sSocketName( sSocketName ),
331*b1cdbd2cSJim Jagielski 		m_sConnectionDescription( sConnectionDescription ),
332*b1cdbd2cSJim Jagielski 		m_nPort( nPort ),
333*b1cdbd2cSJim Jagielski 		m_bTcpNoDelay( bTcpNoDelay ),
334*b1cdbd2cSJim Jagielski 		m_bClosed( sal_False )
335*b1cdbd2cSJim Jagielski 	{
336*b1cdbd2cSJim Jagielski 	}
337*b1cdbd2cSJim Jagielski 
338*b1cdbd2cSJim Jagielski 
init()339*b1cdbd2cSJim Jagielski 	void SocketAcceptor::init()
340*b1cdbd2cSJim Jagielski 	{
341*b1cdbd2cSJim Jagielski 		if( ! m_addr.setPort( m_nPort ) )
342*b1cdbd2cSJim Jagielski 		{
343*b1cdbd2cSJim Jagielski 			OUStringBuffer message( 128 );
344*b1cdbd2cSJim Jagielski 			message.appendAscii( "acc_socket.cxx:SocketAcceptor::init - error - invalid tcp/ip port " );
345*b1cdbd2cSJim Jagielski 			message.append( (sal_Int32) m_nPort );
346*b1cdbd2cSJim Jagielski 			throw ConnectionSetupException(
347*b1cdbd2cSJim Jagielski 				message.makeStringAndClear() , Reference< XInterface> () );
348*b1cdbd2cSJim Jagielski 		}
349*b1cdbd2cSJim Jagielski 		if( ! m_addr.setHostname( m_sSocketName.pData ) )
350*b1cdbd2cSJim Jagielski 		{
351*b1cdbd2cSJim Jagielski 			OUStringBuffer message( 128 );
352*b1cdbd2cSJim Jagielski 			message.appendAscii( "acc_socket.cxx:SocketAcceptor::init - error - invalid host " );
353*b1cdbd2cSJim Jagielski 			message.append( m_sSocketName );
354*b1cdbd2cSJim Jagielski 			throw ConnectionSetupException(
355*b1cdbd2cSJim Jagielski 				message.makeStringAndClear(), Reference< XInterface > () );
356*b1cdbd2cSJim Jagielski 		}
357*b1cdbd2cSJim Jagielski 		m_socket.setOption( osl_Socket_OptionReuseAddr, 1);
358*b1cdbd2cSJim Jagielski 
359*b1cdbd2cSJim Jagielski 		if(! m_socket.bind(m_addr) )
360*b1cdbd2cSJim Jagielski 		{
361*b1cdbd2cSJim Jagielski 			OUStringBuffer message( 128 );
362*b1cdbd2cSJim Jagielski 			message.appendAscii( "acc_socket.cxx:SocketAcceptor::init - error - couldn't bind on " );
363*b1cdbd2cSJim Jagielski 			message.append( m_sSocketName ).appendAscii( ":" ).append((sal_Int32)m_nPort);
364*b1cdbd2cSJim Jagielski 			throw ConnectionSetupException(
365*b1cdbd2cSJim Jagielski 				message.makeStringAndClear(),
366*b1cdbd2cSJim Jagielski 				Reference<XInterface>());
367*b1cdbd2cSJim Jagielski 		}
368*b1cdbd2cSJim Jagielski 
369*b1cdbd2cSJim Jagielski 		if(! m_socket.listen() )
370*b1cdbd2cSJim Jagielski 		{
371*b1cdbd2cSJim Jagielski 			OUStringBuffer message( 128 );
372*b1cdbd2cSJim Jagielski 			message.appendAscii( "acc_socket.cxx:SocketAcceptor::init - error - can't listen on " );
373*b1cdbd2cSJim Jagielski 			message.append( m_sSocketName ).appendAscii( ":" ).append( (sal_Int32) m_nPort);
374*b1cdbd2cSJim Jagielski 			throw ConnectionSetupException(	message.makeStringAndClear(),Reference<XInterface>() );
375*b1cdbd2cSJim Jagielski 		}
376*b1cdbd2cSJim Jagielski 	}
377*b1cdbd2cSJim Jagielski 
accept()378*b1cdbd2cSJim Jagielski 	Reference< XConnection > SocketAcceptor::accept( )
379*b1cdbd2cSJim Jagielski 	{
380*b1cdbd2cSJim Jagielski 		SocketConnection *pConn = new SocketConnection( m_sConnectionDescription );
381*b1cdbd2cSJim Jagielski 
382*b1cdbd2cSJim Jagielski 		if( m_socket.acceptConnection( pConn->m_socket )!= osl_Socket_Ok )
383*b1cdbd2cSJim Jagielski 		{
384*b1cdbd2cSJim Jagielski 			// stopAccepting was called
385*b1cdbd2cSJim Jagielski 			delete pConn;
386*b1cdbd2cSJim Jagielski 			return Reference < XConnection > ();
387*b1cdbd2cSJim Jagielski 		}
388*b1cdbd2cSJim Jagielski 		if( m_bClosed )
389*b1cdbd2cSJim Jagielski 		{
390*b1cdbd2cSJim Jagielski 			delete pConn;
391*b1cdbd2cSJim Jagielski 			return Reference < XConnection > ();
392*b1cdbd2cSJim Jagielski 		}
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski 		pConn->completeConnectionString();
395*b1cdbd2cSJim Jagielski 		if( m_bTcpNoDelay )
396*b1cdbd2cSJim Jagielski 		{
397*b1cdbd2cSJim Jagielski 			sal_Int32 nTcpNoDelay = sal_True;
398*b1cdbd2cSJim Jagielski 			pConn->m_socket.setOption( osl_Socket_OptionTcpNoDelay , &nTcpNoDelay,
399*b1cdbd2cSJim Jagielski 									   sizeof( nTcpNoDelay ) , osl_Socket_LevelTcp );
400*b1cdbd2cSJim Jagielski 		}
401*b1cdbd2cSJim Jagielski 
402*b1cdbd2cSJim Jagielski 		return Reference < XConnection > ( (XConnection * ) pConn );
403*b1cdbd2cSJim Jagielski 	}
404*b1cdbd2cSJim Jagielski 
stopAccepting()405*b1cdbd2cSJim Jagielski 	void SocketAcceptor::stopAccepting()
406*b1cdbd2cSJim Jagielski 	{
407*b1cdbd2cSJim Jagielski 		m_bClosed = sal_True;
408*b1cdbd2cSJim Jagielski 		m_socket.close();
409*b1cdbd2cSJim Jagielski 	}
410*b1cdbd2cSJim Jagielski }
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski 
413