Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsAutoRef_h_
8 : #define nsAutoRef_h_
9 :
10 : #include "mozilla/Attributes.h"
11 :
12 : #include "nscore.h" // for nullptr, bool
13 :
14 : template <class T> class nsSimpleRef;
15 : template <class T> class nsAutoRefBase;
16 : template <class T> class nsReturnRef;
17 : template <class T> class nsReturningRef;
18 :
19 : /**
20 : * template <class T> class nsAutoRef
21 : *
22 : * A class that holds a handle to a resource that must be released.
23 : * No reference is added on construction.
24 : *
25 : * No copy constructor nor copy assignment operators are available, so the
26 : * resource will be held until released on destruction or explicitly
27 : * |reset()| or transferred through provided methods.
28 : *
29 : * The publicly available methods are the public methods on this class and its
30 : * public base classes |nsAutoRefBase<T>| and |nsSimpleRef<T>|.
31 : *
32 : * For ref-counted resources see also |nsCountedRef<T>|.
33 : * For function return values see |nsReturnRef<T>|.
34 : *
35 : * For each class |T|, |nsAutoRefTraits<T>| or |nsSimpleRef<T>| must be
36 : * specialized to use |nsAutoRef<T>| and |nsCountedRef<T>|.
37 : *
38 : * @param T A class identifying the type of reference held by the
39 : * |nsAutoRef<T>| and the unique set methods for managing references
40 : * to the resource (defined by |nsAutoRefTraits<T>| or
41 : * |nsSimpleRef<T>|).
42 : *
43 : * Often this is the class representing the resource. Sometimes a
44 : * new possibly-incomplete class may need to be declared.
45 : *
46 : *
47 : * Example: An Automatically closing file descriptor
48 : *
49 : * // References that are simple integral types (as file-descriptors are)
50 : * // usually need a new class to represent the resource and how to handle its
51 : * // references.
52 : * class nsRawFD;
53 : *
54 : * // Specializing nsAutoRefTraits<nsRawFD> describes how to manage file
55 : * // descriptors, so that nsAutoRef<nsRawFD> provides automatic closing of
56 : * // its file descriptor on destruction.
57 : * template <>
58 : * class nsAutoRefTraits<nsRawFD> {
59 : * public:
60 : * // The file descriptor is held in an int.
61 : * typedef int RawRef;
62 : * // -1 means that there is no file associated with the handle.
63 : * static int Void() { return -1; }
64 : * // The file associated with a file descriptor is released with close().
65 : * static void Release(RawRef aFD) { close(aFD); }
66 : * };
67 : *
68 : * // A function returning a file descriptor that must be closed.
69 : * nsReturnRef<nsRawFD> get_file(const char *filename) {
70 : * // Constructing from a raw file descriptor assumes ownership.
71 : * nsAutoRef<nsRawFD> fd(open(filename, O_RDONLY));
72 : * fcntl(fd, F_SETFD, FD_CLOEXEC);
73 : * return fd.out();
74 : * }
75 : *
76 : * void f() {
77 : * unsigned char buf[1024];
78 : *
79 : * // Hold a file descriptor for /etc/hosts in fd1.
80 : * nsAutoRef<nsRawFD> fd1(get_file("/etc/hosts"));
81 : *
82 : * nsAutoRef<nsRawFD> fd2;
83 : * fd2.steal(fd1); // fd2 takes the file descriptor from fd1
84 : * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file
85 : * count = read(fd2, buf, 1024); // reads from /etc/hosts
86 : *
87 : * // If the file descriptor is not stored then it is closed.
88 : * get_file("/etc/login.defs"); // login.defs is closed
89 : *
90 : * // Now use fd1 to hold a file descriptor for /etc/passwd.
91 : * fd1 = get_file("/etc/passwd");
92 : *
93 : * // The nsAutoRef<nsRawFD> can give up the file descriptor if explicitly
94 : * // instructed, but the caller must then ensure that the file is closed.
95 : * int rawfd = fd1.disown();
96 : *
97 : * // Assume ownership of another file descriptor.
98 : * fd1.own(open("/proc/1/maps");
99 : *
100 : * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts,
101 : * // but /etc/passwd is not closed.
102 : * }
103 : *
104 : */
105 :
106 :
107 : template <class T>
108 1833 : class nsAutoRef : public nsAutoRefBase<T>
109 : {
110 : protected:
111 : typedef nsAutoRef<T> ThisClass;
112 : typedef nsAutoRefBase<T> BaseClass;
113 : typedef nsSimpleRef<T> SimpleRef;
114 : typedef typename BaseClass::RawRefOnly RawRefOnly;
115 : typedef typename BaseClass::LocalSimpleRef LocalSimpleRef;
116 :
117 : public:
118 4312 : nsAutoRef()
119 4312 : {
120 4312 : }
121 :
122 : // Explicit construction is required so as not to risk unintentionally
123 : // releasing the resource associated with a raw ref.
124 1844 : explicit nsAutoRef(RawRefOnly aRefToRelease)
125 1844 : : BaseClass(aRefToRelease)
126 : {
127 1844 : }
128 :
129 : // Construction from a nsReturnRef<T> function return value, which expects
130 : // to give up ownership, transfers ownership.
131 : // (nsReturnRef<T> is converted to const nsReturningRef<T>.)
132 0 : explicit nsAutoRef(const nsReturningRef<T>& aReturning)
133 0 : : BaseClass(aReturning)
134 : {
135 0 : }
136 :
137 : // The only assignment operator provided is for transferring from an
138 : // nsReturnRef smart reference, which expects to pass its ownership to
139 : // another object.
140 : //
141 : // With raw references and other smart references, the type of the lhs and
142 : // its taking and releasing nature is often not obvious from an assignment
143 : // statement. Assignment from a raw ptr especially is not normally
144 : // expected to release the reference.
145 : //
146 : // Use |steal| for taking ownership from other smart refs.
147 : //
148 : // For raw references, use |own| to indicate intention to have the
149 : // resource released.
150 : //
151 : // Or, to create another owner of the same reference, use an nsCountedRef.
152 :
153 0 : ThisClass& operator=(const nsReturningRef<T>& aReturning)
154 : {
155 0 : BaseClass::steal(aReturning.mReturnRef);
156 0 : return *this;
157 : }
158 :
159 : // Conversion to a raw reference allow the nsAutoRef<T> to often be used
160 : // like a raw reference.
161 1135 : operator typename SimpleRef::RawRef() const
162 : {
163 1135 : return this->get();
164 : }
165 :
166 : // Transfer ownership from another smart reference.
167 0 : void steal(ThisClass& aOtherRef)
168 : {
169 0 : BaseClass::steal(aOtherRef);
170 0 : }
171 :
172 : // Assume ownership of a raw ref.
173 : //
174 : // |own| has similar function to |steal|, and is useful for receiving
175 : // ownership from a return value of a function. It is named differently
176 : // because |own| requires more care to ensure that the function intends to
177 : // give away ownership, and so that |steal| can be safely used, knowing
178 : // that it won't steal ownership from any methods returning raw ptrs to
179 : // data owned by a foreign object.
180 3402 : void own(RawRefOnly aRefToRelease)
181 : {
182 3402 : BaseClass::own(aRefToRelease);
183 3402 : }
184 :
185 : // Exchange ownership with |aOther|
186 : void swap(ThisClass& aOther)
187 : {
188 : LocalSimpleRef temp;
189 : temp.SimpleRef::operator=(*this);
190 : SimpleRef::operator=(aOther);
191 : aOther.SimpleRef::operator=(temp);
192 : }
193 :
194 : // Release the reference now.
195 0 : void reset()
196 : {
197 0 : this->SafeRelease();
198 0 : LocalSimpleRef empty;
199 0 : SimpleRef::operator=(empty);
200 0 : }
201 :
202 : // Pass out the reference for a function return values.
203 0 : nsReturnRef<T> out()
204 : {
205 0 : return nsReturnRef<T>(this->disown());
206 : }
207 :
208 : // operator->() and disown() are provided by nsAutoRefBase<T>.
209 : // The default nsSimpleRef<T> provides get().
210 :
211 : private:
212 : // No copy constructor
213 : explicit nsAutoRef(ThisClass& aRefToSteal);
214 : };
215 :
216 : /**
217 : * template <class T> class nsCountedRef
218 : *
219 : * A class that creates (adds) a new reference to a resource on construction
220 : * or assignment and releases on destruction.
221 : *
222 : * This class is similar to nsAutoRef<T> and inherits its methods, but also
223 : * provides copy construction and assignment operators that enable more than
224 : * one concurrent reference to the same resource.
225 : *
226 : * Specialize |nsAutoRefTraits<T>| or |nsSimpleRef<T>| to use this. This
227 : * class assumes that the resource itself counts references and so can only be
228 : * used when |T| represents a reference-counting resource.
229 : */
230 :
231 : template <class T>
232 1805 : class nsCountedRef : public nsAutoRef<T>
233 : {
234 : protected:
235 : typedef nsCountedRef<T> ThisClass;
236 : typedef nsAutoRef<T> BaseClass;
237 : typedef nsSimpleRef<T> SimpleRef;
238 : typedef typename BaseClass::RawRef RawRef;
239 :
240 : public:
241 2614 : nsCountedRef()
242 2614 : {
243 2614 : }
244 :
245 : // Construction and assignment from a another nsCountedRef
246 : // or a raw ref copies and increments the ref count.
247 1698 : nsCountedRef(const ThisClass& aRefToCopy)
248 1698 : {
249 1698 : SimpleRef::operator=(aRefToCopy);
250 1698 : SafeAddRef();
251 1698 : }
252 0 : ThisClass& operator=(const ThisClass& aRefToCopy)
253 : {
254 0 : if (this == &aRefToCopy) {
255 0 : return *this;
256 : }
257 :
258 0 : this->SafeRelease();
259 0 : SimpleRef::operator=(aRefToCopy);
260 0 : SafeAddRef();
261 0 : return *this;
262 : }
263 :
264 : // Implicit conversion from another smart ref argument (to a raw ref) is
265 : // accepted here because construction and assignment safely creates a new
266 : // reference without interfering with the reference to copy.
267 1816 : explicit nsCountedRef(RawRef aRefToCopy)
268 1816 : : BaseClass(aRefToCopy)
269 : {
270 1816 : SafeAddRef();
271 1816 : }
272 3402 : ThisClass& operator=(RawRef aRefToCopy)
273 : {
274 3402 : this->own(aRefToCopy);
275 3402 : SafeAddRef();
276 3402 : return *this;
277 : }
278 :
279 : // Construction and assignment from an nsReturnRef function return value,
280 : // which expects to give up ownership, transfers ownership.
281 : explicit nsCountedRef(const nsReturningRef<T>& aReturning)
282 : : BaseClass(aReturning)
283 : {
284 : }
285 : ThisClass& operator=(const nsReturningRef<T>& aReturning)
286 : {
287 : BaseClass::operator=(aReturning);
288 : return *this;
289 : }
290 :
291 : protected:
292 : // Increase the reference count if there is a resource.
293 6916 : void SafeAddRef()
294 : {
295 6916 : if (this->HaveResource()) {
296 6913 : this->AddRef(this->get());
297 : }
298 6916 : }
299 : };
300 :
301 : /**
302 : * template <class T> class nsReturnRef
303 : *
304 : * A type for function return values that hold a reference to a resource that
305 : * must be released. See also |nsAutoRef<T>::out()|.
306 : */
307 :
308 : template <class T>
309 0 : class nsReturnRef : public nsAutoRefBase<T>
310 : {
311 : protected:
312 : typedef nsAutoRefBase<T> BaseClass;
313 : typedef typename BaseClass::RawRefOnly RawRefOnly;
314 :
315 : public:
316 : // For constructing a return value with no resource
317 0 : nsReturnRef()
318 0 : {
319 0 : }
320 :
321 : // For returning a smart reference from a raw reference that must be
322 : // released. Explicit construction is required so as not to risk
323 : // unintentionally releasing the resource associated with a raw ref.
324 0 : MOZ_IMPLICIT nsReturnRef(RawRefOnly aRefToRelease)
325 0 : : BaseClass(aRefToRelease)
326 : {
327 0 : }
328 :
329 : // Copy construction transfers ownership
330 : nsReturnRef(nsReturnRef<T>& aRefToSteal)
331 : : BaseClass(aRefToSteal)
332 : {
333 : }
334 :
335 0 : MOZ_IMPLICIT nsReturnRef(const nsReturningRef<T>& aReturning)
336 0 : : BaseClass(aReturning)
337 : {
338 0 : }
339 :
340 : // Conversion to a temporary (const) object referring to this object so
341 : // that the reference may be passed from a function return value
342 : // (temporary) to another smart reference. There is no need to use this
343 : // explicitly. Simply assign a nsReturnRef<T> function return value to a
344 : // smart reference.
345 0 : operator nsReturningRef<T>()
346 : {
347 0 : return nsReturningRef<T>(*this);
348 : }
349 :
350 : // No conversion to RawRef operator is provided on nsReturnRef, to ensure
351 : // that the return value is not carelessly assigned to a raw ptr (and the
352 : // resource then released). If passing to a function that takes a raw
353 : // ptr, use get or disown as appropriate.
354 : };
355 :
356 : /**
357 : * template <class T> class nsReturningRef
358 : *
359 : * A class to allow ownership to be transferred from nsReturnRef function
360 : * return values.
361 : *
362 : * It should not be necessary for clients to reference this
363 : * class directly. Simply pass an nsReturnRef<T> to a parameter taking an
364 : * |nsReturningRef<T>|.
365 : *
366 : * The conversion operator on nsReturnRef constructs a temporary wrapper of
367 : * class nsReturningRef<T> around a non-const reference to the nsReturnRef.
368 : * The wrapper can then be passed as an rvalue parameter.
369 : */
370 :
371 : template <class T>
372 : class nsReturningRef
373 : {
374 : private:
375 : friend class nsReturnRef<T>;
376 :
377 0 : explicit nsReturningRef(nsReturnRef<T>& aReturnRef)
378 0 : : mReturnRef(aReturnRef)
379 : {
380 0 : }
381 : public:
382 : nsReturnRef<T>& mReturnRef;
383 : };
384 :
385 : /**
386 : * template <class T> class nsAutoRefTraits
387 : *
388 : * A class describing traits of references managed by the default
389 : * |nsSimpleRef<T>| implementation and thus |nsAutoRef<T>| and |nsCountedRef|.
390 : * The default |nsSimpleRef<T> is suitable for resources with handles that
391 : * have a void value. (If there is no such void value for a handle,
392 : * specialize |nsSimpleRef<T>|.)
393 : *
394 : * Specializations must be provided for each class |T| according to the
395 : * following pattern:
396 : *
397 : * // The template parameter |T| should be a class such that the set of fields
398 : * // in class nsAutoRefTraits<T> is unique for class |T|. Usually the
399 : * // resource object class is sufficient. For handles that are simple
400 : * // integral typedefs, a new unique possibly-incomplete class may need to be
401 : * // declared.
402 : *
403 : * template <>
404 : * class nsAutoRefTraits<T>
405 : * {
406 : * // Specializations must provide a typedef for RawRef, describing the
407 : * // type of the handle to the resource.
408 : * typedef <handle-type> RawRef;
409 : *
410 : * // Specializations should define Void(), a function returning a value
411 : * // suitable for a handle that does not have an associated resource.
412 : * //
413 : * // The return type must be a suitable as the parameter to a RawRef
414 : * // constructor and operator==.
415 : * //
416 : * // If this method is not accessible then some limited nsAutoRef
417 : * // functionality will still be available, but the default constructor,
418 : * // |reset|, and most transfer of ownership methods will not be available.
419 : * static <return-type> Void();
420 : *
421 : * // Specializations must define Release() to properly finalize the
422 : * // handle to a non-void custom-deleted or reference-counted resource.
423 : * static void Release(RawRef aRawRef);
424 : *
425 : * // For reference-counted resources, if |nsCountedRef<T>| is to be used,
426 : * // specializations must define AddRef to increment the reference count
427 : * // held by a non-void handle.
428 : * // (AddRef() is not necessary for |nsAutoRef<T>|.)
429 : * static void AddRef(RawRef aRawRef);
430 : * };
431 : *
432 : * See nsPointerRefTraits for example specializations for simple pointer
433 : * references. See nsAutoRef for an example specialization for a non-pointer
434 : * reference.
435 : */
436 :
437 : template <class T> class nsAutoRefTraits;
438 :
439 : /**
440 : * template <class T> class nsPointerRefTraits
441 : *
442 : * A convenience class useful as a base class for specializations of
443 : * |nsAutoRefTraits<T>| where the handle to the resource is a pointer to |T|.
444 : * By inheriting from this class, definitions of only Release(RawRef) and
445 : * possibly AddRef(RawRef) need to be added.
446 : *
447 : * Examples of use:
448 : *
449 : * template <>
450 : * class nsAutoRefTraits<PRFileDesc> : public nsPointerRefTraits<PRFileDesc>
451 : * {
452 : * public:
453 : * static void Release(PRFileDesc *ptr) { PR_Close(ptr); }
454 : * };
455 : *
456 : * template <>
457 : * class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
458 : * {
459 : * public:
460 : * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); }
461 : * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); }
462 : * };
463 : */
464 :
465 : template <class T>
466 9558 : class nsPointerRefTraits
467 : {
468 : public:
469 : // The handle is a pointer to T.
470 : typedef T* RawRef;
471 : // A nullptr does not have a resource.
472 16463 : static RawRef Void()
473 : {
474 16463 : return nullptr;
475 : }
476 : };
477 :
478 : /**
479 : * template <class T> class nsSimpleRef
480 : *
481 : * Constructs a non-smart reference, and provides methods to test whether
482 : * there is an associated resource and (if so) get its raw handle.
483 : *
484 : * A default implementation is suitable for resources with handles that have a
485 : * void value. This is not intended for direct use but used by |nsAutoRef<T>|
486 : * and thus |nsCountedRef<T>|.
487 : *
488 : * Specialize this class if there is no particular void value for the resource
489 : * handle. A specialized implementation must also provide Release(RawRef),
490 : * and, if |nsCountedRef<T>| is required, AddRef(RawRef), as described in
491 : * nsAutoRefTraits<T>.
492 : */
493 :
494 : template <class T>
495 0 : class nsSimpleRef : protected nsAutoRefTraits<T>
496 : {
497 : protected:
498 : // The default implementation uses nsAutoRefTrait<T>.
499 : // Specializations need not define this typedef.
500 : typedef nsAutoRefTraits<T> Traits;
501 : // The type of the handle to the resource.
502 : // A specialization must provide a typedef for RawRef.
503 : typedef typename Traits::RawRef RawRef;
504 :
505 : // Construct with no resource.
506 : //
507 : // If this constructor is not accessible then some limited nsAutoRef
508 : // functionality will still be available, but the default constructor,
509 : // |reset|, and most transfer of ownership methods will not be available.
510 4312 : nsSimpleRef()
511 4312 : : mRawRef(Traits::Void())
512 : {
513 4312 : }
514 : // Construct with a handle to a resource.
515 : // A specialization must provide this.
516 5246 : explicit nsSimpleRef(RawRef aRawRef)
517 5246 : : mRawRef(aRawRef)
518 : {
519 5246 : }
520 :
521 : // Test whether there is an associated resource. A specialization must
522 : // provide this. The function is permitted to always return true if the
523 : // default constructor is not accessible, or if Release (and AddRef) can
524 : // deal with void handles.
525 12151 : bool HaveResource() const
526 : {
527 12151 : return mRawRef != Traits::Void();
528 : }
529 :
530 : public:
531 : // A specialization must provide get() or loose some functionality. This
532 : // is inherited by derived classes and the specialization may choose
533 : // whether it is public or protected.
534 10798 : RawRef get() const
535 : {
536 10798 : return mRawRef;
537 : }
538 :
539 : private:
540 : RawRef mRawRef;
541 : };
542 :
543 :
544 : /**
545 : * template <class T> class nsAutoRefBase
546 : *
547 : * Internal base class for |nsAutoRef<T>| and |nsReturnRef<T>|.
548 : * Adds release on destruction to a |nsSimpleRef<T>|.
549 : */
550 :
551 : template <class T>
552 : class nsAutoRefBase : public nsSimpleRef<T>
553 : {
554 : protected:
555 : typedef nsAutoRefBase<T> ThisClass;
556 : typedef nsSimpleRef<T> SimpleRef;
557 : typedef typename SimpleRef::RawRef RawRef;
558 :
559 4312 : nsAutoRefBase()
560 4312 : {
561 4312 : }
562 :
563 : // A type for parameters that should be passed a raw ref but should not
564 : // accept implicit conversions (from another smart ref). (The only
565 : // conversion to this type is from a raw ref so only raw refs will be
566 : // accepted.)
567 : class RawRefOnly
568 : {
569 : public:
570 5246 : MOZ_IMPLICIT RawRefOnly(RawRef aRawRef)
571 5246 : : mRawRef(aRawRef)
572 : {
573 5246 : }
574 5246 : operator RawRef() const
575 : {
576 5246 : return mRawRef;
577 : }
578 : private:
579 : RawRef mRawRef;
580 : };
581 :
582 : // Construction from a raw ref assumes ownership
583 1844 : explicit nsAutoRefBase(RawRefOnly aRefToRelease)
584 1844 : : SimpleRef(aRefToRelease)
585 : {
586 1844 : }
587 :
588 : // Constructors that steal ownership
589 : explicit nsAutoRefBase(ThisClass& aRefToSteal)
590 : : SimpleRef(aRefToSteal.disown())
591 : {
592 : }
593 0 : explicit nsAutoRefBase(const nsReturningRef<T>& aReturning)
594 0 : : SimpleRef(aReturning.mReturnRef.disown())
595 : {
596 0 : }
597 :
598 1833 : ~nsAutoRefBase()
599 : {
600 1833 : SafeRelease();
601 1833 : }
602 :
603 : // An internal class providing access to protected nsSimpleRef<T>
604 : // constructors for construction of temporary simple references (that are
605 : // not ThisClass).
606 : class LocalSimpleRef : public SimpleRef
607 : {
608 : public:
609 0 : LocalSimpleRef()
610 0 : {
611 0 : }
612 3402 : explicit LocalSimpleRef(RawRef aRawRef)
613 3402 : : SimpleRef(aRawRef)
614 : {
615 3402 : }
616 : };
617 :
618 : private:
619 : ThisClass& operator=(const ThisClass& aSmartRef) = delete;
620 :
621 : public:
622 128 : RawRef operator->() const
623 : {
624 128 : return this->get();
625 : }
626 :
627 : // Transfer ownership to a raw reference.
628 : //
629 : // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED.
630 : //
631 : // Is this really what you want to use? Using this removes any guarantee
632 : // of release. Use nsAutoRef<T>::out() for return values, or an
633 : // nsAutoRef<T> modifiable lvalue for an out parameter. Use disown() when
634 : // the reference must be stored in a POD type object, such as may be
635 : // preferred for a namespace-scope object with static storage duration,
636 : // for example.
637 0 : RawRef disown()
638 : {
639 0 : RawRef temp = this->get();
640 0 : LocalSimpleRef empty;
641 0 : SimpleRef::operator=(empty);
642 0 : return temp;
643 : }
644 :
645 : protected:
646 : // steal and own are protected because they make no sense on nsReturnRef,
647 : // but steal is implemented on this class for access to aOtherRef.disown()
648 : // when aOtherRef is an nsReturnRef;
649 :
650 : // Transfer ownership from another smart reference.
651 0 : void steal(ThisClass& aOtherRef)
652 : {
653 0 : own(aOtherRef.disown());
654 0 : }
655 : // Assume ownership of a raw ref.
656 3402 : void own(RawRefOnly aRefToRelease)
657 : {
658 3402 : SafeRelease();
659 3402 : LocalSimpleRef ref(aRefToRelease);
660 3402 : SimpleRef::operator=(ref);
661 3402 : }
662 :
663 : // Release a resource if there is one.
664 5235 : void SafeRelease()
665 : {
666 5235 : if (this->HaveResource()) {
667 2622 : this->Release(this->get());
668 : }
669 5235 : }
670 : };
671 :
672 : #endif // !defined(nsAutoRef_h_)
|