xref: /trunk/main/io/source/acceptor/acc_pipe.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_io.hxx"
30 #include "osl/security.hxx"
31 #include "acceptor.hxx"
32 #include <com/sun/star/connection/ConnectionSetupException.hpp>
33 
34 #include <cppuhelper/implbase1.hxx>
35 
36 using namespace ::rtl;
37 using namespace ::osl;
38 using namespace ::cppu;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::connection;
42 using namespace ::com::sun::star::io;
43 
44 
45 namespace io_acceptor
46 {
47 
48     typedef WeakImplHelper1< XConnection > MyPipeConnection;
49 
50     class PipeConnection :
51         public MyPipeConnection
52     {
53     public:
54         PipeConnection( const OUString &sConnectionDescription);
55         ~PipeConnection();
56 
57         virtual sal_Int32 SAL_CALL read( Sequence< sal_Int8 >& aReadBytes, sal_Int32 nBytesToRead )
58             throw(::com::sun::star::io::IOException,
59                   ::com::sun::star::uno::RuntimeException);
60         virtual void SAL_CALL write( const Sequence< sal_Int8 >& aData )
61             throw(::com::sun::star::io::IOException,
62                   ::com::sun::star::uno::RuntimeException);
63         virtual void SAL_CALL flush(  ) throw(
64             ::com::sun::star::io::IOException,
65             ::com::sun::star::uno::RuntimeException);
66         virtual void SAL_CALL close(  )
67             throw(::com::sun::star::io::IOException,
68                   ::com::sun::star::uno::RuntimeException);
69         virtual ::rtl::OUString SAL_CALL getDescription(  )
70             throw(::com::sun::star::uno::RuntimeException);
71     public:
72         ::osl::StreamPipe m_pipe;
73         oslInterlockedCount m_nStatus;
74         OUString m_sDescription;
75     };
76 
77 
78 
79     PipeConnection::PipeConnection( const OUString &sConnectionDescription) :
80         m_nStatus( 0 ),
81         m_sDescription( sConnectionDescription )
82     {
83         g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
84 
85         // make it unique
86         m_sDescription += OUString::createFromAscii( ",uniqueValue=" );
87         m_sDescription += OUString::valueOf(
88             sal::static_int_cast<sal_Int64 >(
89                 reinterpret_cast< sal_IntPtr >(&m_pipe)),
90             10 );
91     }
92 
93     PipeConnection::~PipeConnection()
94     {
95         g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
96     }
97 
98     sal_Int32 PipeConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead )
99         throw(::com::sun::star::io::IOException,
100               ::com::sun::star::uno::RuntimeException)
101     {
102         if( ! m_nStatus )
103         {
104             if( aReadBytes.getLength() < nBytesToRead )
105             {
106                 aReadBytes.realloc( nBytesToRead );
107             }
108             sal_Int32 n = m_pipe.read( aReadBytes.getArray(), nBytesToRead );
109             OSL_ASSERT( n >= 0 && n <= aReadBytes.getLength() );
110             if( n < aReadBytes.getLength() )
111             {
112                 aReadBytes.realloc( n );
113             }
114             return n;
115         }
116         else {
117             throw IOException();
118         }
119     }
120 
121     void PipeConnection::write( const Sequence < sal_Int8 > &seq )
122             throw(::com::sun::star::io::IOException,
123                   ::com::sun::star::uno::RuntimeException)
124     {
125         if( ! m_nStatus )
126         {
127             if( m_pipe.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() )
128             {
129                 throw IOException();
130             }
131         }
132         else {
133             throw IOException();
134         }
135     }
136 
137     void PipeConnection::flush( )
138         throw(  ::com::sun::star::io::IOException,
139                 ::com::sun::star::uno::RuntimeException)
140     {
141     }
142 
143     void PipeConnection::close()
144         throw( ::com::sun::star::io::IOException,
145                ::com::sun::star::uno::RuntimeException)
146     {
147         if(  1 == osl_incrementInterlockedCount( (&m_nStatus) ) )
148         {
149             m_pipe.close();
150         }
151     }
152 
153     OUString PipeConnection::getDescription()
154             throw(::com::sun::star::uno::RuntimeException)
155     {
156         return m_sDescription;
157     }
158 
159     /***************
160      * PipeAcceptor
161      **************/
162     PipeAcceptor::PipeAcceptor( const OUString &sPipeName , const OUString & sConnectionDescription) :
163         m_sPipeName( sPipeName ),
164         m_sConnectionDescription( sConnectionDescription ),
165         m_bClosed( sal_False )
166     {
167     }
168 
169 
170     void PipeAcceptor::init()
171     {
172         m_pipe = Pipe( m_sPipeName.pData , osl_Pipe_CREATE , osl::Security() );
173         if( ! m_pipe.is() )
174         {
175             OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
176             error += m_sPipeName;
177             throw ConnectionSetupException( error, Reference< XInterface > () );
178         }
179     }
180 
181     Reference< XConnection > PipeAcceptor::accept( )
182     {
183         Pipe pipe;
184         {
185             MutexGuard guard( m_mutex );
186             pipe = m_pipe;
187         }
188         if( ! pipe.is() )
189         {
190             OUString error = OUString::createFromAscii( "io.acceptor: pipe already closed" );
191             error += m_sPipeName;
192             throw ConnectionSetupException( error, Reference< XInterface > () );
193         }
194         PipeConnection *pConn = new PipeConnection( m_sConnectionDescription );
195 
196         oslPipeError status = pipe.accept( pConn->m_pipe );
197 
198         if( m_bClosed )
199         {
200             // stopAccepting was called !
201             delete pConn;
202             return Reference < XConnection >();
203         }
204         else if( osl_Pipe_E_None == status )
205         {
206             return Reference < XConnection > ( (XConnection * ) pConn );
207         }
208         else
209         {
210             OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
211             error += m_sPipeName;
212             throw ConnectionSetupException( error, Reference< XInterface > ());
213         }
214     }
215 
216     void PipeAcceptor::stopAccepting()
217     {
218         m_bClosed = sal_True;
219         Pipe pipe;
220         {
221             MutexGuard guard( m_mutex );
222             pipe = m_pipe;
223             m_pipe.clear();
224         }
225         if( pipe.is() )
226         {
227             pipe.close();
228         }
229     }
230 }
231