xref: /aoo4110/main/io/source/acceptor/acc_pipe.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_io.hxx"
26 #include "osl/security.hxx"
27 #include "acceptor.hxx"
28 #include <com/sun/star/connection/ConnectionSetupException.hpp>
29 
30 #include <cppuhelper/implbase1.hxx>
31 
32 using namespace ::rtl;
33 using namespace ::osl;
34 using namespace ::cppu;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::connection;
38 using namespace ::com::sun::star::io;
39 
40 
41 namespace io_acceptor
42 {
43 
44 	typedef WeakImplHelper1< XConnection > MyPipeConnection;
45 
46 	class PipeConnection :
47 		public MyPipeConnection
48 	{
49 	public:
50 		PipeConnection( const OUString &sConnectionDescription);
51 		~PipeConnection();
52 
53 		virtual sal_Int32 SAL_CALL read( Sequence< sal_Int8 >& aReadBytes, sal_Int32 nBytesToRead )
54 			throw(::com::sun::star::io::IOException,
55 				  ::com::sun::star::uno::RuntimeException);
56 		virtual void SAL_CALL write( const Sequence< sal_Int8 >& aData )
57 			throw(::com::sun::star::io::IOException,
58 				  ::com::sun::star::uno::RuntimeException);
59 		virtual void SAL_CALL flush(  ) throw(
60 			::com::sun::star::io::IOException,
61 			::com::sun::star::uno::RuntimeException);
62 		virtual void SAL_CALL close(  )
63 			throw(::com::sun::star::io::IOException,
64 				  ::com::sun::star::uno::RuntimeException);
65 		virtual ::rtl::OUString SAL_CALL getDescription(  )
66 			throw(::com::sun::star::uno::RuntimeException);
67 	public:
68 		::osl::StreamPipe m_pipe;
69 		oslInterlockedCount m_nStatus;
70 		OUString m_sDescription;
71 	};
72 
73 
74 
PipeConnection(const OUString & sConnectionDescription)75 	PipeConnection::PipeConnection( const OUString &sConnectionDescription) :
76 		m_nStatus( 0 ),
77 		m_sDescription( sConnectionDescription )
78 	{
79 		g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
80 
81 		// make it unique
82 		m_sDescription += OUString::createFromAscii( ",uniqueValue=" );
83 		m_sDescription += OUString::valueOf(
84             sal::static_int_cast<sal_Int64 >(
85                 reinterpret_cast< sal_IntPtr >(&m_pipe)),
86             10 );
87 	}
88 
~PipeConnection()89 	PipeConnection::~PipeConnection()
90 	{
91 		g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
92 	}
93 
read(Sequence<sal_Int8> & aReadBytes,sal_Int32 nBytesToRead)94 	sal_Int32 PipeConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead )
95 		throw(::com::sun::star::io::IOException,
96 			  ::com::sun::star::uno::RuntimeException)
97 	{
98 		if( ! m_nStatus )
99 		{
100 			if( aReadBytes.getLength() < nBytesToRead )
101 			{
102 				aReadBytes.realloc( nBytesToRead );
103 			}
104             sal_Int32 n = m_pipe.read( aReadBytes.getArray(), nBytesToRead );
105             OSL_ASSERT( n >= 0 && n <= aReadBytes.getLength() );
106             if( n < aReadBytes.getLength() )
107             {
108                 aReadBytes.realloc( n );
109             }
110 			return n;
111 		}
112 		else {
113 			throw IOException();
114 		}
115 	}
116 
write(const Sequence<sal_Int8> & seq)117 	void PipeConnection::write( const Sequence < sal_Int8 > &seq )
118 			throw(::com::sun::star::io::IOException,
119 				  ::com::sun::star::uno::RuntimeException)
120 	{
121 		if( ! m_nStatus )
122 		{
123 			if( m_pipe.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() )
124 			{
125 				throw IOException();
126 			}
127 		}
128 		else {
129 			throw IOException();
130 		}
131 	}
132 
flush()133 	void PipeConnection::flush( )
134 		throw(	::com::sun::star::io::IOException,
135 				::com::sun::star::uno::RuntimeException)
136 	{
137 	}
138 
close()139 	void PipeConnection::close()
140 		throw( ::com::sun::star::io::IOException,
141 			   ::com::sun::star::uno::RuntimeException)
142 	{
143 		if(  1 == osl_incrementInterlockedCount( (&m_nStatus) ) )
144 		{
145 			m_pipe.close();
146 		}
147 	}
148 
getDescription()149 	OUString PipeConnection::getDescription()
150 			throw(::com::sun::star::uno::RuntimeException)
151 	{
152 		return m_sDescription;
153 	}
154 
155 	/***************
156 	 * PipeAcceptor
157 	 **************/
PipeAcceptor(const OUString & sPipeName,const OUString & sConnectionDescription)158 	PipeAcceptor::PipeAcceptor( const OUString &sPipeName , const OUString & sConnectionDescription) :
159 		m_sPipeName( sPipeName ),
160 		m_sConnectionDescription( sConnectionDescription ),
161 		m_bClosed( sal_False )
162 	{
163 	}
164 
165 
init()166 	void PipeAcceptor::init()
167 	{
168 		m_pipe = Pipe( m_sPipeName.pData , osl_Pipe_CREATE , osl::Security() );
169         if( ! m_pipe.is() )
170         {
171 			OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
172 			error += m_sPipeName;
173             throw ConnectionSetupException( error, Reference< XInterface > () );
174         }
175 	}
176 
accept()177 	Reference< XConnection > PipeAcceptor::accept( )
178 	{
179         Pipe pipe;
180         {
181             MutexGuard guard( m_mutex );
182             pipe = m_pipe;
183         }
184         if( ! pipe.is() )
185         {
186 			OUString error = OUString::createFromAscii( "io.acceptor: pipe already closed" );
187 			error += m_sPipeName;
188             throw ConnectionSetupException( error, Reference< XInterface > () );
189         }
190 		PipeConnection *pConn = new PipeConnection( m_sConnectionDescription );
191 
192 		oslPipeError status = pipe.accept( pConn->m_pipe );
193 
194 		if( m_bClosed )
195 		{
196 			// stopAccepting was called !
197 			delete pConn;
198 			return Reference < XConnection >();
199 		}
200 		else if( osl_Pipe_E_None == status )
201 		{
202 			return Reference < XConnection > ( (XConnection * ) pConn );
203 		}
204 		else
205 		{
206 			OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
207 			error += m_sPipeName;
208 			throw ConnectionSetupException( error, Reference< XInterface > ());
209 		}
210 	}
211 
stopAccepting()212 	void PipeAcceptor::stopAccepting()
213 	{
214 		m_bClosed = sal_True;
215         Pipe pipe;
216         {
217             MutexGuard guard( m_mutex );
218             pipe = m_pipe;
219             m_pipe.clear();
220         }
221         if( pipe.is() )
222         {
223             pipe.close();
224         }
225 	}
226 }
227