sbDeviceEventTesterStressThreads.cpp
Go to the documentation of this file.
1 /* vim: set sw=2 :miv */
2 /*
3 //
4 // BEGIN SONGBIRD GPL
5 //
6 // This file is part of the Songbird web player.
7 //
8 // Copyright(c) 2005-2008 POTI, Inc.
9 // http://songbirdnest.com
10 //
11 // This file may be licensed under the terms of of the
12 // GNU General Public License Version 2 (the "GPL").
13 //
14 // Software distributed under the License is distributed
15 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
16 // express or implied. See the GPL for the specific language
17 // governing rights and limitations.
18 //
19 // You should have received a copy of the GPL along with this
20 // program. If not, go to http://www.gnu.org/licenses/gpl.html
21 // or write to the Free Software Foundation, Inc.,
22 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 // END SONGBIRD GPL
25 //
26 */
27 
29 
30 #include <nsAutoLock.h>
31 #include <nsCOMPtr.h>
32 #include <nsServiceManagerUtils.h>
33 #include <nsThreadUtils.h>
34 #include <nsIGenericFactory.h>
35 
36 #include <sbIDevice.h>
37 #include <sbIDeviceEvent.h>
38 #include <sbIDeviceEventTarget.h>
39 #include <sbIDeviceManager.h>
40 
41 #define STRESS_TEST_THREAD_COUNT 200
42 
44  nsIRunnable,
46 
48  : mMonitor(nsnull),
49  mCounter(-999)
50 {
51  /* member initializers and constructor code */
52 }
53 
54 sbDeviceEventTesterStressThreads::~sbDeviceEventTesterStressThreads()
55 {
56  /* destructor code */
57 }
58 
59 /* void run (); */
60 NS_IMETHODIMP sbDeviceEventTesterStressThreads::Run()
61 {
62  NS_ENSURE_FALSE(mMonitor, NS_ERROR_ALREADY_INITIALIZED);
63 
64  mMonitor = nsAutoMonitor::NewMonitor(__FILE__);
65  NS_ENSURE_TRUE(mMonitor, NS_ERROR_OUT_OF_MEMORY);
66 
67  nsresult rv;
68 
69  nsCOMPtr<sbIDeviceEventTarget> target =
70  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
71  NS_ENSURE_SUCCESS(rv, rv);
72 
73  rv = target->AddEventListener(static_cast<sbIDeviceEventListener*>(this));
74  NS_ENSURE_SUCCESS(rv, rv);
75 
76  // spin up a *ton* of threads...
77  mCounter = 0;
78  for (int i = 0; i < STRESS_TEST_THREAD_COUNT; ++i) {
79  nsAutoMonitor mon(mMonitor);
80  nsCOMPtr<nsIRunnable> event =
81  NS_NEW_RUNNABLE_METHOD(sbDeviceEventTesterStressThreads, this, OnEvent);
82  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
83 
84  nsCOMPtr<nsIThread> thread;
85  ++mCounter;
86  rv = NS_NewThread(getter_AddRefs(thread), event);
87  NS_ENSURE_SUCCESS(rv, rv);
88 
89  mThreads.AppendObject(thread);
90  }
91 
92  // and wait for them
93  while (mThreads.Count()) {
94  nsCOMPtr<nsIThread> thread = mThreads[0];
95  PRBool succeeded = mThreads.RemoveObjectAt(0);
96  NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE);
97  rv = thread->Shutdown();
98  NS_ENSURE_SUCCESS(rv, rv);
99  }
100 
101  rv = target->RemoveEventListener(static_cast<sbIDeviceEventListener*>(this));
102  NS_ENSURE_SUCCESS(rv, rv);
103 
104  NS_ENSURE_TRUE(mCounter == 0, NS_ERROR_FAILURE);
105 
106  return NS_OK;
107 }
108 
109 /* void onDeviceEvent (in sbIDeviceEvent aEvent); */
110 NS_IMETHODIMP sbDeviceEventTesterStressThreads::OnDeviceEvent(sbIDeviceEvent *aEvent)
111 {
112  nsAutoMonitor mon(mMonitor);
113  --mCounter;
114  if (!NS_IsMainThread()) {
115  NS_WARNING("Not on main thread!");
116  mCounter = -2000; // some random error value
117  return NS_ERROR_UNEXPECTED;
118  }
119 
120  return NS_OK;
121 }
122 
123 void sbDeviceEventTesterStressThreads::OnEvent()
124 {
125  nsresult rv;
126  nsCOMPtr<sbIDeviceManager2> manager =
127  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
128  NS_ENSURE_SUCCESS(rv, /* void */);
129 
130  nsCOMPtr<sbIDeviceEventTarget> target = do_QueryInterface(manager);
131  NS_ENSURE_SUCCESS(rv, /* void */);
132 
133  nsCOMPtr<sbIDeviceEvent> event;
134  rv = manager->CreateEvent(sbIDeviceEvent::EVENT_DEVICE_BASE,
135  nsnull,
136  NS_ISUPPORTS_CAST(sbIDeviceEventListener*, this),
139  getter_AddRefs(event));
140  NS_ENSURE_SUCCESS(rv, /* void */);
141 
142  rv = target->DispatchEvent(event, PR_FALSE, nsnull);
143  NS_ENSURE_SUCCESS(rv, /* void */);
144 }
return NS_OK
function succeeded(ch, cx, status, data)
var event
#define STRESS_TEST_THREAD_COUNT
NS_IMPL_THREADSAFE_ISUPPORTS2(sbDeviceEventTesterStressThreads, nsIRunnable, sbIDeviceEventListener) sbDeviceEventTesterStressThreads
const unsigned long STATE_IDLE
Definition: sbIDevice.idl:220
const unsigned long EVENT_DEVICE_BASE
_getSelectedPageStyle s i