VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/glue/nsISupportsImpl.h@ 76900

Last change on this file since 76900 was 65406, checked in by vboxsync, 8 years ago

XPCOM/nsISupportsImpl.h: switch to an extremely paranoid AddRef/Release implementation for the threadsafe variant

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 71.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 XPCOM.
15 *
16 * The Initial Developer of the Original Code is Netscape Communications Corp.
17 * Portions created by the Initial Developer are Copyright (C) 2001
18 * the Initial Developer. All Rights Reserved.
19 *
20 * Contributor(s):
21 *
22 * Alternatively, the contents of this file may be used under the terms of
23 * either the GNU General Public License Version 2 or later (the "GPL"), or
24 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25 * in which case the provisions of the GPL or the LGPL are applicable instead
26 * of those above. If you wish to allow use of your version of this file only
27 * under the terms of either the GPL or the LGPL, and not to allow others to
28 * use your version of this file under the terms of the MPL, indicate your
29 * decision by deleting the provisions above and replace them with the notice
30 * and other provisions required by the GPL or the LGPL. If you do not delete
31 * the provisions above, a recipient may use your version of this file under
32 * the terms of any one of the MPL, the GPL or the LGPL.
33 *
34 * ***** END LICENSE BLOCK ***** */
35
36
37#ifndef nsISupportsImpl_h__
38#define nsISupportsImpl_h__
39
40#ifndef nscore_h___
41#include "nscore.h"
42#endif
43
44#ifndef nsISupportsBase_h__
45#include "nsISupportsBase.h"
46#endif
47
48#include "prthread.h" /* needed for thread-safety checks */
49#include "pratom.h" /* needed for PR_AtomicIncrement and PR_AtomicDecrement */
50
51#include "nsDebug.h"
52#include "nsTraceRefcnt.h"
53#ifdef VBOX
54# include "iprt/asm.h"
55# include "iprt/assert.h"
56#endif
57
58////////////////////////////////////////////////////////////////////////////////
59// Macros to help detect thread-safety:
60
61#if defined(NS_DEBUG)
62
63class nsAutoOwningThread {
64public:
65 nsAutoOwningThread() { mThread = PR_GetCurrentThread(); }
66 void *GetThread() const { return mThread; }
67
68private:
69 void *mThread;
70};
71
72#define NS_DECL_OWNINGTHREAD nsAutoOwningThread _mOwningThread;
73#define NS_ASSERT_OWNINGTHREAD(_class) \
74 NS_CheckThreadSafe(_mOwningThread.GetThread(), #_class " not thread-safe")
75
76#else // !(defined(NS_DEBUG))
77
78#define NS_DECL_OWNINGTHREAD /* nothing */
79#define NS_ASSERT_OWNINGTHREAD(_class) ((void)0)
80
81#endif // !(defined(NS_DEBUG))
82
83class nsAutoRefCnt {
84
85 public:
86 nsAutoRefCnt() : mValue(0)
87#ifdef VBOX
88 , mState(0)
89#endif
90 {}
91 nsAutoRefCnt(nsrefcnt aValue) : mValue(aValue) {}
92
93 // only support prefix increment/decrement
94 nsrefcnt operator++() { return ++mValue; }
95 nsrefcnt operator--() { return --mValue; }
96
97 nsrefcnt operator=(nsrefcnt aValue) { return (mValue = aValue); }
98 operator nsrefcnt() const { return mValue; }
99 nsrefcnt get() const { return mValue; }
100#ifdef VBOX
101 nsrefcnt *ref() { return &mValue; }
102 PRUint32 getState() const { return mState; }
103 PRUint32 *refState() { return &mState; }
104#endif
105 private:
106 // do not define these to enforce the faster prefix notation
107 nsrefcnt operator++(int);
108 nsrefcnt operator--(int);
109 nsrefcnt mValue;
110#ifdef VBOX
111 PRUint32 mState;
112#endif
113};
114
115///////////////////////////////////////////////////////////////////////////////
116
117/**
118 * Declare the reference count variable and the implementations of the
119 * AddRef and QueryInterface methods.
120 */
121
122#define NS_DECL_ISUPPORTS \
123public: \
124 NS_IMETHOD QueryInterface(REFNSIID aIID, \
125 void** aInstancePtr); \
126 NS_IMETHOD_(nsrefcnt) AddRef(void); \
127 NS_IMETHOD_(nsrefcnt) Release(void); \
128protected: \
129 nsAutoRefCnt mRefCnt; \
130 NS_DECL_OWNINGTHREAD \
131public:
132
133
134///////////////////////////////////////////////////////////////////////////////
135
136/**
137 * Previously used to initialize the reference count, but no longer needed.
138 *
139 * DEPRECATED.
140 */
141#define NS_INIT_ISUPPORTS() ((void)0)
142
143/**
144 * Use this macro to implement the AddRef method for a given <i>_class</i>
145 * @param _class The name of the class implementing the method
146 */
147#define NS_IMPL_ADDREF(_class) \
148NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
149{ \
150 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
151 NS_ASSERT_OWNINGTHREAD(_class); \
152 ++mRefCnt; \
153 NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \
154 return mRefCnt; \
155}
156
157/**
158 * Use this macro to implement the AddRef method for a given <i>_class</i>
159 * implemented as a wholly owned aggregated object intended to implement
160 * interface(s) for its owner
161 * @param _class The name of the class implementing the method
162 * @param _aggregator the owning/containing object
163 */
164#define NS_IMPL_ADDREF_USING_AGGREGATOR(_class, _aggregator) \
165NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
166{ \
167 NS_PRECONDITION(_aggregator, "null aggregator"); \
168 return (_aggregator)->AddRef(); \
169}
170
171/**
172 * Use this macro to implement the Release method for a given
173 * <i>_class</i>.
174 * @param _class The name of the class implementing the method
175 * @param _destroy A statement that is executed when the object's
176 * refcount drops to zero.
177 *
178 * For example,
179 *
180 * NS_IMPL_RELEASE_WITH_DESTROY(Foo, Destroy(this))
181 *
182 * will cause
183 *
184 * Destroy(this);
185 *
186 * to be invoked when the object's refcount drops to zero. This
187 * allows for arbitrary teardown activity to occur (e.g., deallocation
188 * of object allocated with placement new).
189 */
190#define NS_IMPL_RELEASE_WITH_DESTROY(_class, _destroy) \
191NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
192{ \
193 NS_PRECONDITION(0 != mRefCnt, "dup release"); \
194 NS_ASSERT_OWNINGTHREAD(_class); \
195 --mRefCnt; \
196 NS_LOG_RELEASE(this, mRefCnt, #_class); \
197 if (mRefCnt == 0) { \
198 mRefCnt = 1; /* stabilize */ \
199 _destroy; \
200 return 0; \
201 } \
202 return mRefCnt; \
203}
204
205/**
206 * Use this macro to implement the Release method for a given <i>_class</i>
207 * @param _class The name of the class implementing the method
208 *
209 * A note on the 'stabilization' of the refcnt to one. At that point,
210 * the object's refcount will have gone to zero. The object's
211 * destructor may trigger code that attempts to QueryInterface() and
212 * Release() 'this' again. Doing so will temporarily increment and
213 * decrement the refcount. (Only a logic error would make one try to
214 * keep a permanent hold on 'this'.) To prevent re-entering the
215 * destructor, we make sure that no balanced refcounting can return
216 * the refcount to |0|.
217 */
218#define NS_IMPL_RELEASE(_class) \
219 NS_IMPL_RELEASE_WITH_DESTROY(_class, NS_DELETEXPCOM(this))
220
221/**
222 * Use this macro to implement the Release method for a given <i>_class</i>
223 * implemented as a wholly owned aggregated object intended to implement
224 * interface(s) for its owner
225 * @param _class The name of the class implementing the method
226 * @param _aggregator the owning/containing object
227 */
228#define NS_IMPL_RELEASE_USING_AGGREGATOR(_class, _aggregator) \
229NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
230{ \
231 NS_PRECONDITION(_aggregator, "null aggregator"); \
232 return (_aggregator)->Release(); \
233}
234
235
236
237///////////////////////////////////////////////////////////////////////////////
238
239/*
240 * Some convenience macros for implementing QueryInterface
241 */
242
243/**
244 * This implements query interface with two assumptions: First, the
245 * class in question implements nsISupports and its own interface and
246 * nothing else. Second, the implementation of the class's primary
247 * inheritance chain leads to its own interface.
248 *
249 * @param _class The name of the class implementing the method
250 * @param _classiiddef The name of the #define symbol that defines the IID
251 * for the class (e.g. NS_ISUPPORTS_IID)
252 */
253
254#define NS_IMPL_QUERY_HEAD(_class) \
255NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
256{ \
257 NS_ASSERTION(aInstancePtr, \
258 "QueryInterface requires a non-NULL destination!"); \
259 nsISupports* foundInterface;
260
261#define NS_IMPL_QUERY_BODY(_interface) \
262 if ( aIID.Equals(NS_GET_IID(_interface)) ) \
263 foundInterface = NS_STATIC_CAST(_interface*, this); \
264 else
265
266#define NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition) \
267 if ( (condition) && aIID.Equals(NS_GET_IID(_interface))) \
268 foundInterface = NS_STATIC_CAST(_interface*, this); \
269 else
270
271#define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass) \
272 if ( aIID.Equals(NS_GET_IID(_interface)) ) \
273 foundInterface = NS_STATIC_CAST(_interface*, \
274 NS_STATIC_CAST(_implClass*, this)); \
275 else
276
277#define NS_IMPL_QUERY_BODY_AGGREGATED(_interface, _aggregate) \
278 if ( aIID.Equals(NS_GET_IID(_interface)) ) \
279 foundInterface = NS_STATIC_CAST(_interface*, _aggregate); \
280 else
281
282#define NS_IMPL_QUERY_TAIL_GUTS \
283 foundInterface = 0; \
284 nsresult status; \
285 if ( !foundInterface ) \
286 status = NS_NOINTERFACE; \
287 else \
288 { \
289 NS_ADDREF(foundInterface); \
290 status = NS_OK; \
291 } \
292 *aInstancePtr = foundInterface; \
293 return status; \
294}
295
296#define NS_IMPL_QUERY_TAIL_INHERITING(_baseclass) \
297 foundInterface = 0; \
298 nsresult status; \
299 if ( !foundInterface ) \
300 status = _baseclass::QueryInterface(aIID, (void**)&foundInterface); \
301 else \
302 { \
303 NS_ADDREF(foundInterface); \
304 status = NS_OK; \
305 } \
306 *aInstancePtr = foundInterface; \
307 return status; \
308}
309
310#define NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator) \
311 foundInterface = 0; \
312 nsresult status; \
313 if ( !foundInterface ) { \
314 NS_ASSERTION(_aggregator, "null aggregator"); \
315 status = _aggregator->QueryInterface(aIID, (void**)&foundInterface); \
316 } else \
317 { \
318 NS_ADDREF(foundInterface); \
319 status = NS_OK; \
320 } \
321 *aInstancePtr = foundInterface; \
322 return status; \
323}
324
325#define NS_IMPL_QUERY_TAIL(_supports_interface) \
326 NS_IMPL_QUERY_BODY_AMBIGUOUS(nsISupports, _supports_interface) \
327 NS_IMPL_QUERY_TAIL_GUTS
328
329
330 /*
331 This is the new scheme. Using this notation now will allow us to switch to
332 a table driven mechanism when it's ready. Note the difference between this
333 and the (currently) underlying NS_IMPL_QUERY_INTERFACE mechanism. You must
334 explicitly mention |nsISupports| when using the interface maps.
335 */
336#define NS_INTERFACE_MAP_BEGIN(_implClass) NS_IMPL_QUERY_HEAD(_implClass)
337#define NS_INTERFACE_MAP_ENTRY(_interface) NS_IMPL_QUERY_BODY(_interface)
338#define NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface, condition) \
339 NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition)
340#define NS_INTERFACE_MAP_ENTRY_AGGREGATED(_interface,_aggregate) \
341 NS_IMPL_QUERY_BODY_AGGREGATED(_interface,_aggregate)
342
343#define NS_INTERFACE_MAP_END NS_IMPL_QUERY_TAIL_GUTS
344#define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass) \
345 NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass)
346#define NS_INTERFACE_MAP_END_INHERITING(_baseClass) \
347 NS_IMPL_QUERY_TAIL_INHERITING(_baseClass)
348#define NS_INTERFACE_MAP_END_AGGREGATED(_aggregator) \
349 NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator)
350
351#define NS_IMPL_QUERY_INTERFACE0(_class) \
352 NS_INTERFACE_MAP_BEGIN(_class) \
353 NS_INTERFACE_MAP_ENTRY(nsISupports) \
354 NS_INTERFACE_MAP_END
355
356#define NS_IMPL_QUERY_INTERFACE1(_class, _i1) \
357 NS_INTERFACE_MAP_BEGIN(_class) \
358 NS_INTERFACE_MAP_ENTRY(_i1) \
359 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
360 NS_INTERFACE_MAP_END
361
362#define NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2) \
363 NS_INTERFACE_MAP_BEGIN(_class) \
364 NS_INTERFACE_MAP_ENTRY(_i1) \
365 NS_INTERFACE_MAP_ENTRY(_i2) \
366 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
367 NS_INTERFACE_MAP_END
368
369#define NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3) \
370 NS_INTERFACE_MAP_BEGIN(_class) \
371 NS_INTERFACE_MAP_ENTRY(_i1) \
372 NS_INTERFACE_MAP_ENTRY(_i2) \
373 NS_INTERFACE_MAP_ENTRY(_i3) \
374 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
375 NS_INTERFACE_MAP_END
376
377#define NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4) \
378 NS_INTERFACE_MAP_BEGIN(_class) \
379 NS_INTERFACE_MAP_ENTRY(_i1) \
380 NS_INTERFACE_MAP_ENTRY(_i2) \
381 NS_INTERFACE_MAP_ENTRY(_i3) \
382 NS_INTERFACE_MAP_ENTRY(_i4) \
383 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
384 NS_INTERFACE_MAP_END
385
386#define NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5) \
387 NS_INTERFACE_MAP_BEGIN(_class) \
388 NS_INTERFACE_MAP_ENTRY(_i1) \
389 NS_INTERFACE_MAP_ENTRY(_i2) \
390 NS_INTERFACE_MAP_ENTRY(_i3) \
391 NS_INTERFACE_MAP_ENTRY(_i4) \
392 NS_INTERFACE_MAP_ENTRY(_i5) \
393 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
394 NS_INTERFACE_MAP_END
395
396#define NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
397 NS_INTERFACE_MAP_BEGIN(_class) \
398 NS_INTERFACE_MAP_ENTRY(_i1) \
399 NS_INTERFACE_MAP_ENTRY(_i2) \
400 NS_INTERFACE_MAP_ENTRY(_i3) \
401 NS_INTERFACE_MAP_ENTRY(_i4) \
402 NS_INTERFACE_MAP_ENTRY(_i5) \
403 NS_INTERFACE_MAP_ENTRY(_i6) \
404 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
405 NS_INTERFACE_MAP_END
406
407#define NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \
408 NS_INTERFACE_MAP_BEGIN(_class) \
409 NS_INTERFACE_MAP_ENTRY(_i1) \
410 NS_INTERFACE_MAP_ENTRY(_i2) \
411 NS_INTERFACE_MAP_ENTRY(_i3) \
412 NS_INTERFACE_MAP_ENTRY(_i4) \
413 NS_INTERFACE_MAP_ENTRY(_i5) \
414 NS_INTERFACE_MAP_ENTRY(_i6) \
415 NS_INTERFACE_MAP_ENTRY(_i7) \
416 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
417 NS_INTERFACE_MAP_END
418
419#define NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
420 _i7, _i8) \
421 NS_INTERFACE_MAP_BEGIN(_class) \
422 NS_INTERFACE_MAP_ENTRY(_i1) \
423 NS_INTERFACE_MAP_ENTRY(_i2) \
424 NS_INTERFACE_MAP_ENTRY(_i3) \
425 NS_INTERFACE_MAP_ENTRY(_i4) \
426 NS_INTERFACE_MAP_ENTRY(_i5) \
427 NS_INTERFACE_MAP_ENTRY(_i6) \
428 NS_INTERFACE_MAP_ENTRY(_i7) \
429 NS_INTERFACE_MAP_ENTRY(_i8) \
430 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
431 NS_INTERFACE_MAP_END
432
433#define NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
434 _i7, _i8, _i9) \
435 NS_INTERFACE_MAP_BEGIN(_class) \
436 NS_INTERFACE_MAP_ENTRY(_i1) \
437 NS_INTERFACE_MAP_ENTRY(_i2) \
438 NS_INTERFACE_MAP_ENTRY(_i3) \
439 NS_INTERFACE_MAP_ENTRY(_i4) \
440 NS_INTERFACE_MAP_ENTRY(_i5) \
441 NS_INTERFACE_MAP_ENTRY(_i6) \
442 NS_INTERFACE_MAP_ENTRY(_i7) \
443 NS_INTERFACE_MAP_ENTRY(_i8) \
444 NS_INTERFACE_MAP_ENTRY(_i9) \
445 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
446 NS_INTERFACE_MAP_END
447
448#define NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
449 _i7, _i8, _i9, _i10) \
450 NS_INTERFACE_MAP_BEGIN(_class) \
451 NS_INTERFACE_MAP_ENTRY(_i1) \
452 NS_INTERFACE_MAP_ENTRY(_i2) \
453 NS_INTERFACE_MAP_ENTRY(_i3) \
454 NS_INTERFACE_MAP_ENTRY(_i4) \
455 NS_INTERFACE_MAP_ENTRY(_i5) \
456 NS_INTERFACE_MAP_ENTRY(_i6) \
457 NS_INTERFACE_MAP_ENTRY(_i7) \
458 NS_INTERFACE_MAP_ENTRY(_i8) \
459 NS_INTERFACE_MAP_ENTRY(_i9) \
460 NS_INTERFACE_MAP_ENTRY(_i10) \
461 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
462 NS_INTERFACE_MAP_END
463
464#define NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
465 _i7, _i8, _i9, _i10, _i11) \
466 NS_INTERFACE_MAP_BEGIN(_class) \
467 NS_INTERFACE_MAP_ENTRY(_i1) \
468 NS_INTERFACE_MAP_ENTRY(_i2) \
469 NS_INTERFACE_MAP_ENTRY(_i3) \
470 NS_INTERFACE_MAP_ENTRY(_i4) \
471 NS_INTERFACE_MAP_ENTRY(_i5) \
472 NS_INTERFACE_MAP_ENTRY(_i6) \
473 NS_INTERFACE_MAP_ENTRY(_i7) \
474 NS_INTERFACE_MAP_ENTRY(_i8) \
475 NS_INTERFACE_MAP_ENTRY(_i9) \
476 NS_INTERFACE_MAP_ENTRY(_i10) \
477 NS_INTERFACE_MAP_ENTRY(_i11) \
478 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
479 NS_INTERFACE_MAP_END
480
481
482#define NS_IMPL_THREADSAFE_QUERY_INTERFACE0 NS_IMPL_QUERY_INTERFACE0
483#define NS_IMPL_THREADSAFE_QUERY_INTERFACE1 NS_IMPL_QUERY_INTERFACE1
484#define NS_IMPL_THREADSAFE_QUERY_INTERFACE2 NS_IMPL_QUERY_INTERFACE2
485#define NS_IMPL_THREADSAFE_QUERY_INTERFACE3 NS_IMPL_QUERY_INTERFACE3
486#define NS_IMPL_THREADSAFE_QUERY_INTERFACE4 NS_IMPL_QUERY_INTERFACE4
487#define NS_IMPL_THREADSAFE_QUERY_INTERFACE5 NS_IMPL_QUERY_INTERFACE5
488#define NS_IMPL_THREADSAFE_QUERY_INTERFACE6 NS_IMPL_QUERY_INTERFACE6
489#define NS_IMPL_THREADSAFE_QUERY_INTERFACE7 NS_IMPL_QUERY_INTERFACE7
490#define NS_IMPL_THREADSAFE_QUERY_INTERFACE8 NS_IMPL_QUERY_INTERFACE8
491#define NS_IMPL_THREADSAFE_QUERY_INTERFACE9 NS_IMPL_QUERY_INTERFACE9
492#define NS_IMPL_THREADSAFE_QUERY_INTERFACE10 NS_IMPL_QUERY_INTERFACE10
493#define NS_IMPL_THREADSAFE_QUERY_INTERFACE11 NS_IMPL_QUERY_INTERFACE11
494
495/**
496 * Declare that you're going to inherit from something that already
497 * implements nsISupports, but also implements an additional interface, thus
498 * causing an ambiguity. In this case you don't need another mRefCnt, you
499 * just need to forward the definitions to the appropriate superclass. E.g.
500 *
501 * class Bar : public Foo, public nsIBar { // both provide nsISupports
502 * public:
503 * NS_DECL_ISUPPORTS_INHERITED
504 * ...other nsIBar and Bar methods...
505 * };
506 */
507#define NS_DECL_ISUPPORTS_INHERITED \
508public: \
509 NS_IMETHOD QueryInterface(REFNSIID aIID, \
510 void** aInstancePtr); \
511 NS_IMETHOD_(nsrefcnt) AddRef(void); \
512 NS_IMETHOD_(nsrefcnt) Release(void); \
513
514/**
515 * These macros can be used in conjunction with NS_DECL_ISUPPORTS_INHERITED
516 * to implement the nsISupports methods, forwarding the invocations to a
517 * superclass that already implements nsISupports.
518 *
519 * Note that I didn't make these inlined because they're virtual methods.
520 */
521
522#define NS_IMPL_ADDREF_INHERITED(Class, Super) \
523NS_IMETHODIMP_(nsrefcnt) Class::AddRef(void) \
524{ \
525 return Super::AddRef(); \
526} \
527
528#define NS_IMPL_RELEASE_INHERITED(Class, Super) \
529NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
530{ \
531 return Super::Release(); \
532} \
533
534#define NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
535 NS_IMPL_QUERY_HEAD(Class) \
536 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
537
538#define NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \
539 NS_IMPL_QUERY_HEAD(Class) \
540 NS_IMPL_QUERY_BODY(i1) \
541 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
542
543#define NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \
544 NS_IMPL_QUERY_HEAD(Class) \
545 NS_IMPL_QUERY_BODY(i1) \
546 NS_IMPL_QUERY_BODY(i2) \
547 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
548
549#define NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \
550 NS_IMPL_QUERY_HEAD(Class) \
551 NS_IMPL_QUERY_BODY(i1) \
552 NS_IMPL_QUERY_BODY(i2) \
553 NS_IMPL_QUERY_BODY(i3) \
554 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
555
556#define NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \
557 NS_IMPL_QUERY_HEAD(Class) \
558 NS_IMPL_QUERY_BODY(i1) \
559 NS_IMPL_QUERY_BODY(i2) \
560 NS_IMPL_QUERY_BODY(i3) \
561 NS_IMPL_QUERY_BODY(i4) \
562 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
563
564#define NS_IMPL_QUERY_INTERFACE_INHERITED5(Class,Super,i1,i2,i3,i4,i5) \
565 NS_IMPL_QUERY_HEAD(Class) \
566 NS_IMPL_QUERY_BODY(i1) \
567 NS_IMPL_QUERY_BODY(i2) \
568 NS_IMPL_QUERY_BODY(i3) \
569 NS_IMPL_QUERY_BODY(i4) \
570 NS_IMPL_QUERY_BODY(i5) \
571 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
572
573#define NS_IMPL_QUERY_INTERFACE_INHERITED6(Class,Super,i1,i2,i3,i4,i5,i6) \
574 NS_IMPL_QUERY_HEAD(Class) \
575 NS_IMPL_QUERY_BODY(i1) \
576 NS_IMPL_QUERY_BODY(i2) \
577 NS_IMPL_QUERY_BODY(i3) \
578 NS_IMPL_QUERY_BODY(i4) \
579 NS_IMPL_QUERY_BODY(i5) \
580 NS_IMPL_QUERY_BODY(i6) \
581 NS_IMPL_QUERY_TAIL_INHERITING(Super) \
582
583/**
584 * Convenience macros for implementing all nsISupports methods for
585 * a simple class.
586 * @param _class The name of the class implementing the method
587 * @param _classiiddef The name of the #define symbol that defines the IID
588 * for the class (e.g. NS_ISUPPORTS_IID)
589 */
590
591#define NS_IMPL_ISUPPORTS0(_class) \
592 NS_IMPL_ADDREF(_class) \
593 NS_IMPL_RELEASE(_class) \
594 NS_IMPL_QUERY_INTERFACE0(_class)
595
596#define NS_IMPL_ISUPPORTS1(_class, _interface) \
597 NS_IMPL_ADDREF(_class) \
598 NS_IMPL_RELEASE(_class) \
599 NS_IMPL_QUERY_INTERFACE1(_class, _interface)
600
601#define NS_IMPL_ISUPPORTS2(_class, _i1, _i2) \
602 NS_IMPL_ADDREF(_class) \
603 NS_IMPL_RELEASE(_class) \
604 NS_IMPL_QUERY_INTERFACE2(_class, _i1, _i2)
605
606#define NS_IMPL_ISUPPORTS3(_class, _i1, _i2, _i3) \
607 NS_IMPL_ADDREF(_class) \
608 NS_IMPL_RELEASE(_class) \
609 NS_IMPL_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
610
611#define NS_IMPL_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \
612 NS_IMPL_ADDREF(_class) \
613 NS_IMPL_RELEASE(_class) \
614 NS_IMPL_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
615
616#define NS_IMPL_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \
617 NS_IMPL_ADDREF(_class) \
618 NS_IMPL_RELEASE(_class) \
619 NS_IMPL_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
620
621#define NS_IMPL_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
622 NS_IMPL_ADDREF(_class) \
623 NS_IMPL_RELEASE(_class) \
624 NS_IMPL_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
625
626#define NS_IMPL_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \
627 NS_IMPL_ADDREF(_class) \
628 NS_IMPL_RELEASE(_class) \
629 NS_IMPL_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)
630
631#define NS_IMPL_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \
632 NS_IMPL_ADDREF(_class) \
633 NS_IMPL_RELEASE(_class) \
634 NS_IMPL_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)
635
636#define NS_IMPL_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
637 _i9) \
638 NS_IMPL_ADDREF(_class) \
639 NS_IMPL_RELEASE(_class) \
640 NS_IMPL_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9)
641
642#define NS_IMPL_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
643 _i9, _i10) \
644 NS_IMPL_ADDREF(_class) \
645 NS_IMPL_RELEASE(_class) \
646 NS_IMPL_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
647 _i9, _i10)
648
649#define NS_IMPL_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
650 _i9, _i10, _i11) \
651 NS_IMPL_ADDREF(_class) \
652 NS_IMPL_RELEASE(_class) \
653 NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
654 _i9, _i10, _i11)
655
656#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \
657 NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
658 NS_IMPL_ADDREF_INHERITED(Class, Super) \
659 NS_IMPL_RELEASE_INHERITED(Class, Super) \
660
661#define NS_IMPL_ISUPPORTS_INHERITED1(Class, Super, i1) \
662 NS_IMPL_QUERY_INTERFACE_INHERITED1(Class, Super, i1) \
663 NS_IMPL_ADDREF_INHERITED(Class, Super) \
664 NS_IMPL_RELEASE_INHERITED(Class, Super) \
665
666#define NS_IMPL_ISUPPORTS_INHERITED2(Class, Super, i1, i2) \
667 NS_IMPL_QUERY_INTERFACE_INHERITED2(Class, Super, i1, i2) \
668 NS_IMPL_ADDREF_INHERITED(Class, Super) \
669 NS_IMPL_RELEASE_INHERITED(Class, Super) \
670
671#define NS_IMPL_ISUPPORTS_INHERITED3(Class, Super, i1, i2, i3) \
672 NS_IMPL_QUERY_INTERFACE_INHERITED3(Class, Super, i1, i2, i3) \
673 NS_IMPL_ADDREF_INHERITED(Class, Super) \
674 NS_IMPL_RELEASE_INHERITED(Class, Super) \
675
676#define NS_IMPL_ISUPPORTS_INHERITED4(Class, Super, i1, i2, i3, i4) \
677 NS_IMPL_QUERY_INTERFACE_INHERITED4(Class, Super, i1, i2, i3, i4) \
678 NS_IMPL_ADDREF_INHERITED(Class, Super) \
679 NS_IMPL_RELEASE_INHERITED(Class, Super) \
680
681#define NS_IMPL_ISUPPORTS_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \
682 NS_IMPL_QUERY_INTERFACE_INHERITED5(Class, Super, i1, i2, i3, i4, i5) \
683 NS_IMPL_ADDREF_INHERITED(Class, Super) \
684 NS_IMPL_RELEASE_INHERITED(Class, Super) \
685
686#define NS_IMPL_ISUPPORTS_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \
687 NS_IMPL_QUERY_INTERFACE_INHERITED6(Class, Super, i1, i2, i3, i4, i5, i6) \
688 NS_IMPL_ADDREF_INHERITED(Class, Super) \
689 NS_IMPL_RELEASE_INHERITED(Class, Super) \
690
691///////////////////////////////////////////////////////////////////////////////
692/**
693 *
694 * Threadsafe implementations of the ISupports convenience macros
695 *
696 */
697
698/**
699 * Use this macro to implement the AddRef method for a given <i>_class</i>
700 * @param _class The name of the class implementing the method
701 */
702
703#ifdef VBOX
704#define NS_IMPL_THREADSAFE_ADDREF(_class) \
705NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
706{ \
707 nsrefcnt count = mRefCnt.get(); \
708 PRUint32 state = mRefCnt.getState(); \
709 AssertReleaseMsg( state <= 1 \
710 && ( (state == 0 && count == 0) \
711 || (state == 1 && count < PR_UINT32_MAX/2)), \
712 ("AddRef: illegal refcnt=%u state=%d\n", count, state)); \
713 switch (state) \
714 { \
715 case 0: \
716 if (!ASMAtomicCmpXchgU32(mRefCnt.refState(), 1, 0)) \
717 AssertReleaseMsgFailed(("AddRef: racing for first increment\n")); \
718 count = ASMAtomicIncU32(mRefCnt.ref()); \
719 AssertReleaseMsg(count == 1, \
720 ("AddRef: unexpected refcnt=%u\n", count)); \
721 break; \
722 case 1: \
723 count = ASMAtomicIncU32(mRefCnt.ref()); \
724 AssertReleaseMsg(count <= PR_UINT32_MAX/2, \
725 ("AddRef: unexpected refcnt=%u\n", count)); \
726 break; \
727 case 2: \
728 AssertReleaseMsgFailed(("AddRef: freed object\n")); \
729 break; \
730 default: \
731 AssertReleaseMsgFailed(("AddRef: garbage object\n")); \
732 } \
733 NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
734 return count; \
735}
736#else
737#define NS_IMPL_THREADSAFE_ADDREF(_class) \
738NS_IMETHODIMP_(nsrefcnt) _class::AddRef(void) \
739{ \
740 NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt"); \
741 nsrefcnt count; \
742 count = PR_AtomicIncrement((PRInt32*)&mRefCnt); \
743 NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
744 return count; \
745}
746#endif
747
748/**
749 * Use this macro to implement the Release method for a given <i>_class</i>
750 * @param _class The name of the class implementing the method
751 */
752
753#ifdef VBOX
754#define NS_IMPL_THREADSAFE_RELEASE(_class) \
755NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
756{ \
757 nsrefcnt count = mRefCnt.get(); \
758 PRUint32 state = mRefCnt.getState(); \
759 AssertReleaseMsg(state == 1 && count <= PR_UINT32_MAX/2, \
760 ("Release: illegal refcnt=%u state=%d\n", count, state)); \
761 switch (state) \
762 { \
763 case 0: \
764 AssertReleaseMsgFailed(("Release: new object\n")); \
765 break; \
766 case 1: \
767 count = ASMAtomicDecU32(mRefCnt.ref()); \
768 AssertReleaseMsg(count < PR_UINT32_MAX/2, \
769 ("Release: unexpected refcnt=%u\n", count)); \
770 if (count == 0) \
771 { \
772 if (!ASMAtomicCmpXchgU32(mRefCnt.refState(), 2, 1)) \
773 AssertReleaseMsgFailed(("Release: racing for state free\n")); \
774 /* Use better stabilization: reserve everything with top bit set. */ \
775 if (!ASMAtomicCmpXchgU32(mRefCnt.ref(), PR_UINT32_MAX/4*3, 0)) \
776 AssertReleaseMsgFailed(("Release: racing for refcnt stabilize\n")); \
777 NS_DELETEXPCOM(this); \
778 } \
779 break; \
780 case 2: \
781 AssertReleaseMsgFailed(("Release: freed object\n")); \
782 break; \
783 default: \
784 AssertReleaseMsgFailed(("Release: garbage object\n")); \
785 } \
786 NS_LOG_RELEASE(this, count, #_class); \
787 return count; \
788}
789#else
790#define NS_IMPL_THREADSAFE_RELEASE(_class) \
791NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
792{ \
793 nsrefcnt count; \
794 NS_PRECONDITION(0 != mRefCnt, "dup release"); \
795 count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); \
796 NS_LOG_RELEASE(this, count, #_class); \
797 if (0 == count) { \
798 mRefCnt = 1; /* stabilize */ \
799 /* enable this to find non-threadsafe destructors: */ \
800 /* NS_ASSERT_OWNINGTHREAD(_class); */ \
801 NS_DELETEXPCOM(this); \
802 return 0; \
803 } \
804 return count; \
805}
806#endif
807
808#define NS_IMPL_THREADSAFE_ISUPPORTS0(_class) \
809 NS_IMPL_THREADSAFE_ADDREF(_class) \
810 NS_IMPL_THREADSAFE_RELEASE(_class) \
811 NS_IMPL_THREADSAFE_QUERY_INTERFACE0(_class)
812
813#define NS_IMPL_THREADSAFE_ISUPPORTS1(_class, _interface) \
814 NS_IMPL_THREADSAFE_ADDREF(_class) \
815 NS_IMPL_THREADSAFE_RELEASE(_class) \
816 NS_IMPL_THREADSAFE_QUERY_INTERFACE1(_class, _interface)
817
818#define NS_IMPL_THREADSAFE_ISUPPORTS2(_class, _i1, _i2) \
819 NS_IMPL_THREADSAFE_ADDREF(_class) \
820 NS_IMPL_THREADSAFE_RELEASE(_class) \
821 NS_IMPL_THREADSAFE_QUERY_INTERFACE2(_class, _i1, _i2)
822
823#define NS_IMPL_THREADSAFE_ISUPPORTS3(_class, _i1, _i2, _i3) \
824 NS_IMPL_THREADSAFE_ADDREF(_class) \
825 NS_IMPL_THREADSAFE_RELEASE(_class) \
826 NS_IMPL_THREADSAFE_QUERY_INTERFACE3(_class, _i1, _i2, _i3)
827
828#define NS_IMPL_THREADSAFE_ISUPPORTS4(_class, _i1, _i2, _i3, _i4) \
829 NS_IMPL_THREADSAFE_ADDREF(_class) \
830 NS_IMPL_THREADSAFE_RELEASE(_class) \
831 NS_IMPL_THREADSAFE_QUERY_INTERFACE4(_class, _i1, _i2, _i3, _i4)
832
833#define NS_IMPL_THREADSAFE_ISUPPORTS5(_class, _i1, _i2, _i3, _i4, _i5) \
834 NS_IMPL_THREADSAFE_ADDREF(_class) \
835 NS_IMPL_THREADSAFE_RELEASE(_class) \
836 NS_IMPL_THREADSAFE_QUERY_INTERFACE5(_class, _i1, _i2, _i3, _i4, _i5)
837
838#define NS_IMPL_THREADSAFE_ISUPPORTS6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
839 NS_IMPL_THREADSAFE_ADDREF(_class) \
840 NS_IMPL_THREADSAFE_RELEASE(_class) \
841 NS_IMPL_THREADSAFE_QUERY_INTERFACE6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
842
843#define NS_IMPL_THREADSAFE_ISUPPORTS7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
844 _i7) \
845 NS_IMPL_THREADSAFE_ADDREF(_class) \
846 NS_IMPL_THREADSAFE_RELEASE(_class) \
847 NS_IMPL_THREADSAFE_QUERY_INTERFACE7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
848 _i7)
849
850#define NS_IMPL_THREADSAFE_ISUPPORTS8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
851 _i7, _i8) \
852 NS_IMPL_THREADSAFE_ADDREF(_class) \
853 NS_IMPL_THREADSAFE_RELEASE(_class) \
854 NS_IMPL_THREADSAFE_QUERY_INTERFACE8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
855 _i7, _i8)
856
857#define NS_IMPL_THREADSAFE_ISUPPORTS9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
858 _i7, _i8, _i9) \
859 NS_IMPL_THREADSAFE_ADDREF(_class) \
860 NS_IMPL_THREADSAFE_RELEASE(_class) \
861 NS_IMPL_THREADSAFE_QUERY_INTERFACE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
862 _i7, _i8, _i9)
863
864#define NS_IMPL_THREADSAFE_ISUPPORTS10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
865 _i7, _i8, _i9, _i10) \
866 NS_IMPL_THREADSAFE_ADDREF(_class) \
867 NS_IMPL_THREADSAFE_RELEASE(_class) \
868 NS_IMPL_THREADSAFE_QUERY_INTERFACE10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
869 _i7, _i8, _i9, _i10)
870
871#define NS_IMPL_THREADSAFE_ISUPPORTS11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
872 _i7, _i8, _i9, _i10, _i11) \
873 NS_IMPL_THREADSAFE_ADDREF(_class) \
874 NS_IMPL_THREADSAFE_RELEASE(_class) \
875 NS_IMPL_THREADSAFE_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
876 _i7, _i8, _i9, _i10, _i11)
877
878///////////////////////////////////////////////////////////////////////////////
879// Macros for implementing nsIClassInfo-related stuff.
880///////////////////////////////////////////////////////////////////////////////
881
882// include here instead of at the top because it requires the nsISupport decl
883#include "nsIClassInfo.h"
884
885#define NS_CLASSINFO_NAME(_class) _class##_classInfoGlobal
886#define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper
887
888#define NS_DECL_CI_INTERFACE_GETTER(_class) \
889 extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *, \
890 nsIID ***);
891
892#define NS_DECL_CLASSINFO(_class) \
893 NS_DECL_CI_INTERFACE_GETTER(_class) \
894 nsIClassInfo *NS_CLASSINFO_NAME(_class);
895
896#define NS_IMPL_QUERY_CLASSINFO(_class) \
897 if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) { \
898 extern nsIClassInfo *NS_CLASSINFO_NAME(_class); \
899 foundInterface = NS_STATIC_CAST(nsIClassInfo*, NS_CLASSINFO_NAME(_class));\
900 } else
901
902#define NS_CLASSINFO_HELPER_BEGIN(_class, _c) \
903NS_IMETHODIMP \
904NS_CI_INTERFACE_GETTER_NAME(_class)(PRUint32 *count, nsIID ***array) \
905{ \
906 *count = _c; \
907 *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c);
908
909#define NS_CLASSINFO_HELPER_ENTRY(_i, _interface) \
910 (*array)[_i] = (nsIID *)nsMemory::Clone(&NS_GET_IID(_interface), \
911 sizeof(nsIID));
912
913#define NS_CLASSINFO_HELPER_END \
914 return NS_OK; \
915}
916
917#define NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface) \
918 NS_CLASSINFO_HELPER_BEGIN(_class, 1) \
919 NS_CLASSINFO_HELPER_ENTRY(0, _interface) \
920 NS_CLASSINFO_HELPER_END
921
922#define NS_IMPL_QUERY_INTERFACE1_CI(_class, _i1) \
923 NS_INTERFACE_MAP_BEGIN(_class) \
924 NS_INTERFACE_MAP_ENTRY(_i1) \
925 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
926 NS_IMPL_QUERY_CLASSINFO(_class) \
927 NS_INTERFACE_MAP_END
928
929#define NS_IMPL_ISUPPORTS1_CI(_class, _interface) \
930 NS_IMPL_ADDREF(_class) \
931 NS_IMPL_RELEASE(_class) \
932 NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface) \
933 NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface)
934
935#define NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2) \
936 NS_CLASSINFO_HELPER_BEGIN(_class, 2) \
937 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
938 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
939 NS_CLASSINFO_HELPER_END
940
941#define NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \
942 NS_INTERFACE_MAP_BEGIN(_class) \
943 NS_INTERFACE_MAP_ENTRY(_i1) \
944 NS_INTERFACE_MAP_ENTRY(_i2) \
945 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
946 NS_IMPL_QUERY_CLASSINFO(_class) \
947 NS_INTERFACE_MAP_END
948
949#define NS_IMPL_ISUPPORTS2_CI(_class, _i1, _i2) \
950 NS_IMPL_ADDREF(_class) \
951 NS_IMPL_RELEASE(_class) \
952 NS_IMPL_QUERY_INTERFACE2_CI(_class, _i1, _i2) \
953 NS_IMPL_CI_INTERFACE_GETTER2(_class, _i1, _i2)
954
955#define NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3) \
956 NS_CLASSINFO_HELPER_BEGIN(_class, 3) \
957 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
958 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
959 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
960 NS_CLASSINFO_HELPER_END
961
962#define NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \
963 NS_INTERFACE_MAP_BEGIN(_class) \
964 NS_INTERFACE_MAP_ENTRY(_i1) \
965 NS_INTERFACE_MAP_ENTRY(_i2) \
966 NS_INTERFACE_MAP_ENTRY(_i3) \
967 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
968 NS_IMPL_QUERY_CLASSINFO(_class) \
969 NS_INTERFACE_MAP_END
970
971#define NS_IMPL_ISUPPORTS3_CI(_class, _i1, _i2, _i3) \
972 NS_IMPL_ADDREF(_class) \
973 NS_IMPL_RELEASE(_class) \
974 NS_IMPL_QUERY_INTERFACE3_CI(_class, _i1, _i2, _i3) \
975 NS_IMPL_CI_INTERFACE_GETTER3(_class, _i1, _i2, _i3)
976
977#define NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4) \
978 NS_CLASSINFO_HELPER_BEGIN(_class, 4) \
979 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
980 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
981 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
982 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
983 NS_CLASSINFO_HELPER_END
984
985#define NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \
986 NS_INTERFACE_MAP_BEGIN(_class) \
987 NS_INTERFACE_MAP_ENTRY(_i1) \
988 NS_INTERFACE_MAP_ENTRY(_i2) \
989 NS_INTERFACE_MAP_ENTRY(_i3) \
990 NS_INTERFACE_MAP_ENTRY(_i4) \
991 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
992 NS_IMPL_QUERY_CLASSINFO(_class) \
993 NS_INTERFACE_MAP_END
994
995#define NS_IMPL_ISUPPORTS4_CI(_class, _i1, _i2, _i3, _i4) \
996 NS_IMPL_ADDREF(_class) \
997 NS_IMPL_RELEASE(_class) \
998 NS_IMPL_QUERY_INTERFACE4_CI(_class, _i1, _i2, _i3, _i4) \
999 NS_IMPL_CI_INTERFACE_GETTER4(_class, _i1, _i2, _i3, _i4)
1000
1001#define NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5) \
1002 NS_CLASSINFO_HELPER_BEGIN(_class, 5) \
1003 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1004 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1005 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1006 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1007 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1008 NS_CLASSINFO_HELPER_END
1009
1010#define NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \
1011 NS_INTERFACE_MAP_BEGIN(_class) \
1012 NS_INTERFACE_MAP_ENTRY(_i1) \
1013 NS_INTERFACE_MAP_ENTRY(_i2) \
1014 NS_INTERFACE_MAP_ENTRY(_i3) \
1015 NS_INTERFACE_MAP_ENTRY(_i4) \
1016 NS_INTERFACE_MAP_ENTRY(_i5) \
1017 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1018 NS_IMPL_QUERY_CLASSINFO(_class) \
1019 NS_INTERFACE_MAP_END
1020
1021#define NS_IMPL_ISUPPORTS5_CI(_class, _i1, _i2, _i3, _i4, _i5) \
1022 NS_IMPL_ADDREF(_class) \
1023 NS_IMPL_RELEASE(_class) \
1024 NS_IMPL_QUERY_INTERFACE5_CI(_class, _i1, _i2, _i3, _i4, _i5) \
1025 NS_IMPL_CI_INTERFACE_GETTER5(_class, _i1, _i2, _i3, _i4, _i5)
1026
1027#define NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1028 NS_CLASSINFO_HELPER_BEGIN(_class, 6) \
1029 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1030 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1031 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1032 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1033 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1034 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1035 NS_CLASSINFO_HELPER_END
1036
1037#define NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1038 NS_INTERFACE_MAP_BEGIN(_class) \
1039 NS_INTERFACE_MAP_ENTRY(_i1) \
1040 NS_INTERFACE_MAP_ENTRY(_i2) \
1041 NS_INTERFACE_MAP_ENTRY(_i3) \
1042 NS_INTERFACE_MAP_ENTRY(_i4) \
1043 NS_INTERFACE_MAP_ENTRY(_i5) \
1044 NS_INTERFACE_MAP_ENTRY(_i6) \
1045 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1046 NS_IMPL_QUERY_CLASSINFO(_class) \
1047 NS_INTERFACE_MAP_END
1048
1049#define NS_IMPL_ISUPPORTS6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1050 NS_IMPL_ADDREF(_class) \
1051 NS_IMPL_RELEASE(_class) \
1052 NS_IMPL_QUERY_INTERFACE6_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6) \
1053 NS_IMPL_CI_INTERFACE_GETTER6(_class, _i1, _i2, _i3, _i4, _i5, _i6)
1054
1055#define NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1056 _i7) \
1057 NS_CLASSINFO_HELPER_BEGIN(_class, 7) \
1058 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1059 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1060 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1061 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1062 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1063 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1064 NS_CLASSINFO_HELPER_ENTRY(6, _i7) \
1065 NS_CLASSINFO_HELPER_END
1066
1067#define NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1068 _i7) \
1069 NS_INTERFACE_MAP_BEGIN(_class) \
1070 NS_INTERFACE_MAP_ENTRY(_i1) \
1071 NS_INTERFACE_MAP_ENTRY(_i2) \
1072 NS_INTERFACE_MAP_ENTRY(_i3) \
1073 NS_INTERFACE_MAP_ENTRY(_i4) \
1074 NS_INTERFACE_MAP_ENTRY(_i5) \
1075 NS_INTERFACE_MAP_ENTRY(_i6) \
1076 NS_INTERFACE_MAP_ENTRY(_i7) \
1077 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1078 NS_IMPL_QUERY_CLASSINFO(_class) \
1079 NS_INTERFACE_MAP_END
1080
1081#define NS_IMPL_ISUPPORTS7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \
1082 NS_IMPL_ADDREF(_class) \
1083 NS_IMPL_RELEASE(_class) \
1084 NS_IMPL_QUERY_INTERFACE7_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7) \
1085 NS_IMPL_CI_INTERFACE_GETTER7(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7)
1086
1087#define NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1088 _i7, _i8) \
1089 NS_CLASSINFO_HELPER_BEGIN(_class, 8) \
1090 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1091 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1092 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1093 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1094 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1095 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1096 NS_CLASSINFO_HELPER_ENTRY(6, _i7) \
1097 NS_CLASSINFO_HELPER_ENTRY(7, _i8) \
1098 NS_CLASSINFO_HELPER_END
1099
1100#define NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1101 _i7, _i8) \
1102 NS_INTERFACE_MAP_BEGIN(_class) \
1103 NS_INTERFACE_MAP_ENTRY(_i1) \
1104 NS_INTERFACE_MAP_ENTRY(_i2) \
1105 NS_INTERFACE_MAP_ENTRY(_i3) \
1106 NS_INTERFACE_MAP_ENTRY(_i4) \
1107 NS_INTERFACE_MAP_ENTRY(_i5) \
1108 NS_INTERFACE_MAP_ENTRY(_i6) \
1109 NS_INTERFACE_MAP_ENTRY(_i7) \
1110 NS_INTERFACE_MAP_ENTRY(_i8) \
1111 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1112 NS_IMPL_QUERY_CLASSINFO(_class) \
1113 NS_INTERFACE_MAP_END
1114
1115#define NS_IMPL_ISUPPORTS8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \
1116 NS_IMPL_ADDREF(_class) \
1117 NS_IMPL_RELEASE(_class) \
1118 NS_IMPL_QUERY_INTERFACE8_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8) \
1119 NS_IMPL_CI_INTERFACE_GETTER8(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8)
1120
1121#define NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1122 _i7, _i8, _i9) \
1123 NS_CLASSINFO_HELPER_BEGIN(_class, 9) \
1124 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1125 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1126 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1127 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1128 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1129 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1130 NS_CLASSINFO_HELPER_ENTRY(6, _i7) \
1131 NS_CLASSINFO_HELPER_ENTRY(7, _i8) \
1132 NS_CLASSINFO_HELPER_ENTRY(8, _i9) \
1133 NS_CLASSINFO_HELPER_END
1134
1135#define NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1136 _i7, _i8, _i9) \
1137 NS_INTERFACE_MAP_BEGIN(_class) \
1138 NS_INTERFACE_MAP_ENTRY(_i1) \
1139 NS_INTERFACE_MAP_ENTRY(_i2) \
1140 NS_INTERFACE_MAP_ENTRY(_i3) \
1141 NS_INTERFACE_MAP_ENTRY(_i4) \
1142 NS_INTERFACE_MAP_ENTRY(_i5) \
1143 NS_INTERFACE_MAP_ENTRY(_i6) \
1144 NS_INTERFACE_MAP_ENTRY(_i7) \
1145 NS_INTERFACE_MAP_ENTRY(_i8) \
1146 NS_INTERFACE_MAP_ENTRY(_i9) \
1147 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1148 NS_IMPL_QUERY_CLASSINFO(_class) \
1149 NS_INTERFACE_MAP_END
1150
1151#define NS_IMPL_ISUPPORTS9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1152 _i8, _i9) \
1153 NS_IMPL_ADDREF(_class) \
1154 NS_IMPL_RELEASE(_class) \
1155 NS_IMPL_QUERY_INTERFACE9_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1156 _i8, _i9) \
1157 NS_IMPL_CI_INTERFACE_GETTER9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1158 _i8, _i9)
1159
1160#define NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1161 _i7, _i8, _i9, _i10) \
1162 NS_CLASSINFO_HELPER_BEGIN(_class, 10) \
1163 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1164 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1165 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1166 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1167 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1168 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1169 NS_CLASSINFO_HELPER_ENTRY(6, _i7) \
1170 NS_CLASSINFO_HELPER_ENTRY(7, _i8) \
1171 NS_CLASSINFO_HELPER_ENTRY(8, _i9) \
1172 NS_CLASSINFO_HELPER_ENTRY(9, _i10) \
1173 NS_CLASSINFO_HELPER_END
1174
1175#define NS_IMPL_CI_INTERFACE_GETTER11(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1176 _i7, _i8, _i9, _i10, _i11) \
1177 NS_CLASSINFO_HELPER_BEGIN(_class, 10) \
1178 NS_CLASSINFO_HELPER_ENTRY(0, _i1) \
1179 NS_CLASSINFO_HELPER_ENTRY(1, _i2) \
1180 NS_CLASSINFO_HELPER_ENTRY(2, _i3) \
1181 NS_CLASSINFO_HELPER_ENTRY(3, _i4) \
1182 NS_CLASSINFO_HELPER_ENTRY(4, _i5) \
1183 NS_CLASSINFO_HELPER_ENTRY(5, _i6) \
1184 NS_CLASSINFO_HELPER_ENTRY(6, _i7) \
1185 NS_CLASSINFO_HELPER_ENTRY(7, _i8) \
1186 NS_CLASSINFO_HELPER_ENTRY(8, _i9) \
1187 NS_CLASSINFO_HELPER_ENTRY(9, _i10) \
1188 NS_CLASSINFO_HELPER_ENTRY(10, _i11) \
1189 NS_CLASSINFO_HELPER_END
1190
1191#define NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1192 _i7, _i8, _i9, _i10) \
1193 NS_INTERFACE_MAP_BEGIN(_class) \
1194 NS_INTERFACE_MAP_ENTRY(_i1) \
1195 NS_INTERFACE_MAP_ENTRY(_i2) \
1196 NS_INTERFACE_MAP_ENTRY(_i3) \
1197 NS_INTERFACE_MAP_ENTRY(_i4) \
1198 NS_INTERFACE_MAP_ENTRY(_i5) \
1199 NS_INTERFACE_MAP_ENTRY(_i6) \
1200 NS_INTERFACE_MAP_ENTRY(_i7) \
1201 NS_INTERFACE_MAP_ENTRY(_i8) \
1202 NS_INTERFACE_MAP_ENTRY(_i9) \
1203 NS_INTERFACE_MAP_ENTRY(_i10) \
1204 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1205 NS_IMPL_QUERY_CLASSINFO(_class) \
1206 NS_INTERFACE_MAP_END
1207
1208#define NS_IMPL_QUERY_INTERFACE11_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
1209 _i7, _i8, _i9, _i10, _i11) \
1210 NS_INTERFACE_MAP_BEGIN(_class) \
1211 NS_INTERFACE_MAP_ENTRY(_i1) \
1212 NS_INTERFACE_MAP_ENTRY(_i2) \
1213 NS_INTERFACE_MAP_ENTRY(_i3) \
1214 NS_INTERFACE_MAP_ENTRY(_i4) \
1215 NS_INTERFACE_MAP_ENTRY(_i5) \
1216 NS_INTERFACE_MAP_ENTRY(_i6) \
1217 NS_INTERFACE_MAP_ENTRY(_i7) \
1218 NS_INTERFACE_MAP_ENTRY(_i8) \
1219 NS_INTERFACE_MAP_ENTRY(_i9) \
1220 NS_INTERFACE_MAP_ENTRY(_i10) \
1221 NS_INTERFACE_MAP_ENTRY(_i11) \
1222 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, _i1) \
1223 NS_IMPL_QUERY_CLASSINFO(_class) \
1224 NS_INTERFACE_MAP_END
1225
1226#define NS_IMPL_ISUPPORTS10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1227 _i8, _i9, _i10) \
1228 NS_IMPL_ADDREF(_class) \
1229 NS_IMPL_RELEASE(_class) \
1230 NS_IMPL_QUERY_INTERFACE10_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1231 _i8, _i9, _i10) \
1232 NS_IMPL_CI_INTERFACE_GETTER10(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1233 _i8, _i9, _i10)
1234
1235#define NS_IMPL_ISUPPORTS11_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1236 _i8, _i9, _i10, _i11) \
1237 NS_IMPL_ADDREF(_class) \
1238 NS_IMPL_RELEASE(_class) \
1239 NS_IMPL_QUERY_INTERFACE11_CI(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1240 _i8, _i9, _i10, _i11) \
1241 NS_IMPL_CI_INTERFACE_GETTER11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
1242 _i8, _i9, _i10, _i11)
1243
1244#define NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_QUERY_TAIL_GUTS
1245
1246#endif
Note: See TracBrowser for help on using the repository browser.

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