Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 : #ifndef _MEDIATOR_HXX
29 : #define _MEDIATOR_HXX
30 :
31 : #include <string.h>
32 : #include <tools/link.hxx>
33 : #include <osl/pipe.hxx>
34 : #include <osl/mutex.hxx>
35 : #include <osl/conditn.hxx>
36 : #include <osl/thread.hxx>
37 :
38 : #include <vector>
39 :
40 : struct MediatorMessage
41 : {
42 : sal_uLong m_nID;
43 : sal_uLong m_nBytes;
44 : char* m_pBytes;
45 : char* m_pRun;
46 :
47 : MediatorMessage() : m_nID( 0 ), m_nBytes( 0 ),
48 : m_pBytes( NULL ), m_pRun( NULL ) {}
49 0 : MediatorMessage( sal_uLong nID, sal_uLong nBytes, char* pBytes ) :
50 0 : m_nID( nID ),m_nBytes( nBytes ), m_pRun( NULL )
51 : {
52 0 : m_pBytes = new char[ m_nBytes ];
53 0 : memcpy( m_pBytes, pBytes, (size_t)m_nBytes );
54 0 : }
55 :
56 0 : ~MediatorMessage()
57 : {
58 0 : if( m_pBytes )
59 0 : delete [] m_pBytes;
60 0 : }
61 :
62 : void Set( sal_uLong nBytes, char* pBytes )
63 : {
64 : if( m_pBytes )
65 : delete [] m_pBytes;
66 : m_nBytes = nBytes;
67 : m_pBytes = new char[ m_nBytes ];
68 : memcpy( m_pBytes, pBytes, (size_t)m_nBytes );
69 : }
70 :
71 : sal_uLong ExtractULONG();
72 : char* GetString();
73 : sal_uInt32 GetUINT32();
74 : void* GetBytes( sal_uLong& );
75 0 : void* GetBytes() { sal_uLong nBytes; return GetBytes( nBytes ); }
76 :
77 : void Rewind() { m_pRun = NULL; }
78 : };
79 :
80 : class MediatorListener;
81 :
82 : class Mediator
83 : {
84 : friend class MediatorListener;
85 : protected:
86 : int m_nSocket;
87 :
88 : std::vector<MediatorMessage*> m_aMessageQueue;
89 : osl::Mutex m_aQueueMutex;
90 : osl::Mutex m_aSendMutex;
91 : // only one thread can send a message at any given time
92 : osl::Condition m_aNewMessageCdtn;
93 : MediatorListener* m_pListener;
94 : // thread to fill the queue
95 :
96 : sal_uLong m_nCurrentID;
97 : // will be constantly increased with each message sent
98 : bool m_bValid;
99 :
100 : Link m_aConnectionLostHdl;
101 : Link m_aNewMessageHdl;
102 : public:
103 : Mediator( int nSocket );
104 : virtual ~Mediator();
105 :
106 : // mark mediator as invalid. No more messages will be processed,
107 : // SendMessage, WaitForMessage, TransactMessage will return immediately
108 : // with error
109 0 : void invalidate() { m_bValid = false; }
110 :
111 : sal_uLong SendMessage( sal_uLong nBytes, const char* pBytes, sal_uLong nMessageID = 0 );
112 : sal_uLong SendMessage( const OString& rMessage, sal_uLong nMessageID = 0 )
113 : {
114 : return SendMessage( rMessage.getLength(), rMessage.getStr(), nMessageID );
115 : }
116 :
117 : sal_Bool WaitForMessage( sal_uLong nTimeOut = 5000 );
118 : // timeout in ms
119 : // TRUE: Message came in
120 : // FALSE: timed out
121 : // if timeout is set, WaitForMessage will wait even if there are messages
122 : // in the queue
123 :
124 : virtual MediatorMessage* WaitForAnswer( sal_uLong nMessageID );
125 : // wait for an answer message ( ID >= 1 << 24 )
126 : // the message will be removed from the queue and returned
127 :
128 : MediatorMessage* TransactMessage( sal_uLong nBytes, char* pBytes );
129 : // sends a message and waits for an answer
130 :
131 : MediatorMessage* GetNextMessage( sal_Bool bWait = sal_False );
132 :
133 :
134 0 : Link SetConnectionLostHdl( const Link& rLink )
135 : {
136 0 : Link aRet = m_aConnectionLostHdl;
137 0 : m_aConnectionLostHdl = rLink;
138 0 : return aRet;
139 : }
140 :
141 0 : Link SetNewMessageHdl( const Link& rLink )
142 : {
143 0 : Link aRet = m_aNewMessageHdl;
144 0 : m_aNewMessageHdl = rLink;
145 0 : return aRet;
146 : }
147 : };
148 :
149 : class MediatorListener : public osl::Thread
150 : {
151 : friend class Mediator;
152 : private:
153 : Mediator* m_pMediator;
154 : ::osl::Mutex m_aMutex;
155 :
156 : MediatorListener( Mediator* );
157 : virtual ~MediatorListener();
158 :
159 : virtual void run() SAL_OVERRIDE;
160 : virtual void onTerminated() SAL_OVERRIDE;
161 : };
162 :
163 : #endif // _MEDIATOR_HXX
164 :
165 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|