xref: /AOO41X/main/io/source/acceptor/acc_pipe.cxx (revision 3716f815df2d68347af345f8524e39097ef453f6)
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