Line data Source code
1 : /*
2 : * Copyright (C) 2010 Google Inc. All rights reserved.
3 : *
4 : * Redistribution and use in source and binary forms, with or without
5 : * modification, are permitted provided that the following conditions
6 : * are met:
7 : *
8 : * 1. Redistributions of source code must retain the above copyright
9 : * notice, this list of conditions and the following disclaimer.
10 : * 2. Redistributions in binary form must reproduce the above copyright
11 : * notice, this list of conditions and the following disclaimer in the
12 : * documentation and/or other materials provided with the distribution.
13 : * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 : * its contributors may be used to endorse or promote products derived
15 : * from this software without specific prior written permission.
16 : *
17 : * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 : * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 : * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 : * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 : * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 : * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : */
28 :
29 : #ifndef HRTFDatabaseLoader_h
30 : #define HRTFDatabaseLoader_h
31 :
32 : #include "nsHashKeys.h"
33 : #include "mozilla/RefPtr.h"
34 : #include "mozilla/MemoryReporting.h"
35 : #include "mozilla/Mutex.h"
36 : #include "HRTFDatabase.h"
37 :
38 : template <class EntryType> class nsTHashtable;
39 : template <class T> class nsAutoRef;
40 :
41 : namespace WebCore {
42 :
43 : // HRTFDatabaseLoader will asynchronously load the default HRTFDatabase in a new thread.
44 :
45 : class HRTFDatabaseLoader {
46 : public:
47 : // Lazily creates a HRTFDatabaseLoader (if not already created) for the given sample-rate
48 : // and starts loading asynchronously (when created the first time).
49 : // Returns the HRTFDatabaseLoader.
50 : // Must be called from the main thread.
51 : static already_AddRefed<HRTFDatabaseLoader> createAndLoadAsynchronouslyIfNecessary(float sampleRate);
52 :
53 : // AddRef and Release may be called from any thread.
54 0 : void AddRef()
55 : {
56 : #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
57 : int count =
58 : #endif
59 0 : ++m_refCnt;
60 0 : MOZ_ASSERT(count > 0, "invalid ref count");
61 0 : NS_LOG_ADDREF(this, count, "HRTFDatabaseLoader", sizeof(*this));
62 0 : }
63 :
64 0 : void Release()
65 : {
66 : // The last reference can't be removed on a non-main thread because
67 : // the object can be accessed on the main thread from the hash
68 : // table via createAndLoadAsynchronouslyIfNecessary().
69 0 : int count = m_refCnt;
70 0 : MOZ_ASSERT(count > 0, "extra release");
71 : // Optimization attempt to possibly skip proxying the release to the
72 : // main thread.
73 0 : if (count != 1 && m_refCnt.compareExchange(count, count - 1)) {
74 0 : NS_LOG_RELEASE(this, count - 1, "HRTFDatabaseLoader");
75 0 : return;
76 : }
77 :
78 0 : ProxyRelease();
79 : }
80 :
81 : // Returns true once the default database has been completely loaded.
82 : bool isLoaded() const;
83 :
84 : // waitForLoaderThreadCompletion() may be called more than once,
85 : // on any thread except m_databaseLoaderThread.
86 : void waitForLoaderThreadCompletion();
87 :
88 0 : HRTFDatabase* database() { return m_hrtfDatabase.get(); }
89 :
90 0 : float databaseSampleRate() const { return m_databaseSampleRate; }
91 :
92 : static void shutdown();
93 :
94 : // Called in asynchronous loading thread.
95 : void load();
96 :
97 : // Sums the size of all cached database loaders.
98 : static size_t sizeOfLoaders(mozilla::MallocSizeOf aMallocSizeOf);
99 :
100 : private:
101 : // Both constructor and destructor must be called from the main thread.
102 : explicit HRTFDatabaseLoader(float sampleRate);
103 : ~HRTFDatabaseLoader();
104 :
105 : size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
106 :
107 : void ProxyRelease(); // any thread
108 : void MainThreadRelease(); // main thread only
109 : class ProxyReleaseEvent;
110 :
111 : // If it hasn't already been loaded, creates a new thread and initiates asynchronous loading of the default database.
112 : // This must be called from the main thread.
113 : void loadAsynchronously();
114 :
115 : // Map from sample-rate to loader.
116 0 : class LoaderByRateEntry : public nsFloatHashKey {
117 : public:
118 0 : explicit LoaderByRateEntry(KeyTypePointer aKey)
119 0 : : nsFloatHashKey(aKey)
120 0 : , mLoader() // so PutEntry() will zero-initialize
121 : {
122 0 : }
123 :
124 0 : size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
125 : {
126 0 : return mLoader ? mLoader->sizeOfIncludingThis(aMallocSizeOf) : 0;
127 : }
128 :
129 : HRTFDatabaseLoader* mLoader;
130 : };
131 :
132 : // Keeps track of loaders on a per-sample-rate basis.
133 : static nsTHashtable<LoaderByRateEntry> *s_loaderMap; // singleton
134 :
135 : mozilla::Atomic<int> m_refCnt;
136 :
137 : nsAutoRef<HRTFDatabase> m_hrtfDatabase;
138 :
139 : // Holding a m_threadLock is required when accessing m_databaseLoaderThread.
140 : mozilla::Mutex m_threadLock;
141 : PRThread* m_databaseLoaderThread;
142 :
143 : float m_databaseSampleRate;
144 : };
145 :
146 : } // namespace WebCore
147 :
148 : #endif // HRTFDatabaseLoader_h
|