VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/transmngr/module/tmQueue.cpp@ 101893

Last change on this file since 101893 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Mozilla Transaction Manager.
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corp.
18 * Portions created by the Initial Developer are Copyright (C) 2003
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * John Gaunt <[email protected]>
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include "plstr.h"
39#include "tmQueue.h"
40#include "tmTransaction.h"
41#include "tmTransactionManager.h"
42#include "tmUtils.h"
43
44///////////////////////////////////////////////////////////////////////////////
45// Constructors & Destructor
46
47tmQueue::~tmQueue() {
48
49 // empty the vectors
50 PRUint32 index = 0;
51 PRUint32 size = mTransactions.Size();
52 for ( ; index < size ; index++) {
53 if (mTransactions[index])
54 delete (tmTransaction *)mTransactions[index];
55 }
56
57 // don't need to delete the mListeners because
58 // we just insert PRUint32s, no allocation
59
60 mTM = nsnull;
61 mID = 0;
62 if (mName)
63 PL_strfree(mName);
64}
65
66///////////////////////////////////////////////////////////////////////////////
67// Public Methods
68
69PRInt32
70tmQueue::Init(const char* aName, PRUint32 aID, tmTransactionManager *aTM) {
71 PR_ASSERT(mTM == nsnull);
72
73 if (NS_SUCCEEDED(mTransactions.Init()) &&
74 NS_SUCCEEDED(mListeners.Init()) &&
75 ((mName = PL_strdup(aName)) != nsnull) ) {
76 mTM = aTM;
77 mID = aID;
78 return NS_OK;
79 }
80 return -1;
81}
82
83PRInt32
84tmQueue::AttachClient(PRUint32 aClientID) {
85
86 PRInt32 status = NS_OK; // success of adding client
87
88 if (!IsAttached(aClientID)) {
89 // add the client to the listener list -- null safe call
90 status = mListeners.Append((void*) aClientID);
91 }
92 else
93 status = -2;
94
95 // create & init a reply transaction
96 tmTransaction trans;
97 if (NS_SUCCEEDED(trans.Init(aClientID, // owner's ipc ID
98 mID, // client gets our ID
99 TM_ATTACH_REPLY, // action
100 status, // success of the add
101 (PRUint8*)mName, // client matches name to ID
102 PL_strlen(mName)+1))) {
103 // send the reply
104 mTM->SendTransaction(aClientID, &trans);
105 }
106
107 // if we successfully added the client - send all current transactions
108 if (status >= 0) { // append returns the index of the added element
109
110 PRUint32 size = mTransactions.Size();
111 for (PRUint32 index = 0; index < size; index++) {
112 if (mTransactions[index])
113 mTM->SendTransaction(aClientID, (tmTransaction*) mTransactions[index]);
114 }
115 }
116 return status;
117}
118
119PRInt32
120tmQueue::DetachClient(PRUint32 aClientID) {
121
122 PRUint32 size = mListeners.Size();
123 PRUint32 id = 0;
124 PRInt32 status = -1;
125
126 for (PRUint32 index = 0; index < size; index++) {
127 id = (PRUint32)NS_PTR_TO_INT32(mListeners[index]);
128 if(id == aClientID) {
129 mListeners.RemoveAt(index);
130 status = NS_OK;
131 break;
132 }
133 }
134
135 tmTransaction trans;
136 if (NS_SUCCEEDED(trans.Init(aClientID,
137 mID,
138 TM_DETACH_REPLY,
139 status,
140 nsnull,
141 0))) {
142 // send the reply
143 mTM->SendTransaction(aClientID, &trans);
144 }
145
146 // if we've removed all the listeners, remove the queue.
147 if (mListeners.Size() == 0)
148 return TM_SUCCESS_DELETE_QUEUE;
149 return status;
150}
151
152void
153tmQueue::FlushQueue(PRUint32 aClientID) {
154
155 if(!IsAttached(aClientID))
156 return;
157
158 PRUint32 size = mTransactions.Size();
159 for (PRUint32 index = 0; index < size; index++)
160 if (mTransactions[index])
161 delete (tmTransaction*)mTransactions[index];
162
163 mTransactions.Clear();
164
165 tmTransaction trans;
166 if (NS_SUCCEEDED(trans.Init(aClientID,
167 mID,
168 TM_FLUSH_REPLY,
169 NS_OK,
170 nsnull,
171 0))) {
172 mTM->SendTransaction(aClientID, &trans);
173 }
174}
175
176PRInt32
177tmQueue::PostTransaction(tmTransaction *aTrans) {
178
179 PRInt32 status = -1;
180 PRUint32 ownerID = aTrans->GetOwnerID();
181
182 // if we are attached, have the right queue and have successfully
183 // appended the transaction to the queue, send the transaction
184 // to all the listeners.
185
186 if (IsAttached(ownerID) && aTrans->GetQueueID() == mID)
187 status = mTransactions.Append(aTrans);
188
189 if (status >= 0) {
190 // send the transaction to all members of mListeners except the owner
191 PRUint32 size = mListeners.Size();
192 PRUint32 id = 0;
193 for (PRUint32 index = 0; index < size; index++) {
194 id = (PRUint32)NS_PTR_TO_INT32(mListeners[index]);
195 if (ownerID != id)
196 mTM->SendTransaction(id, aTrans);
197 }
198 }
199
200 tmTransaction trans;
201 if (NS_SUCCEEDED(trans.Init(ownerID,
202 mID,
203 TM_POST_REPLY,
204 status,
205 nsnull,
206 0))) {
207 // send the reply
208 mTM->SendTransaction(ownerID, &trans);
209 }
210 return status;
211}
212
213PRBool
214tmQueue::IsAttached(PRUint32 aClientID) {
215 // XXX could be an issue if the aClientID is 0 and there
216 // is a "hole" in the mListeners vector. - may NEED to store PRUint32*s
217 PRUint32 size = mListeners.Size();
218 for (PRUint32 index = 0; index < size; index++) {
219 if (aClientID == (PRUint32)NS_PTR_TO_INT32(mListeners[index]))
220 return PR_TRUE;
221 }
222 return PR_FALSE;
223}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette