sbRequestThreadQueue.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2011 POTI, Inc.
9  * http://www.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 #ifndef SBREQUESTTHREADQUEUE_H_
28 #define SBREQUESTTHREADQUEUE_H_
29 
30 // Platform includes
31 #include <algorithm>
32 #include <deque>
33 #include <list>
34 
35 // Mozilla includes
36 #include <nsAutoLock.h>
37 #include <nsAutoPtr.h>
38 #include <nsCOMPtr.h>
39 
40 #include <prlock.h>
41 
42 // Mozilla interfaces
43 #include <nsIClassInfo.h>
44 #include <nsIRunnable.h>
45 #include <nsIThread.h>
46 #include <nsITimer.h>
47 
48 // Local includes
49 #include "sbRequestItem.h"
50 
66 {
67 public:
68 
69  NS_IMETHOD_(nsrefcnt) AddRef(void);
70  NS_IMETHOD_(nsrefcnt) Release(void);
71 
77  class Batch
78  {
79  typedef std::list<sbRequestItem *> RequestItems;
80  public:
81  // types
82  typedef RequestItems::const_iterator const_iterator;
83  typedef RequestItems::iterator iterator;
84  typedef RequestItems::size_type size_type;
85  typedef RequestItems::reference reference;
86  typedef RequestItems::const_reference const_reference;
87 
88  Batch();
89  ~Batch();
90 
95  {
96  return mRequestItems.begin();
97  }
98 
103  {
104  return mRequestItems.begin();
105  }
106 
111  {
112  return mRequestItems.end();
113  }
114 
119  {
120  return mRequestItems.end();
121  }
122 
128  {
129  return mRequestItems.size();
130  }
134  PRUint32 CountableItems() const
135  {
136  return mCountableItems;
137  }
138 
142  PRUint32 RequestType() const
143  {
144  return mRequestType;
145  }
146 
150  void push_back(sbRequestItem * aItem);
151 
156  void erase(iterator aIter);
157 
161  bool empty() const
162  {
163  return mRequestItems.empty();
164  }
165 
170  iterator insert(iterator aIter, sbRequestItem * aRequestItem)
171  {
172  NS_ASSERTION(aRequestItem,
173  "sbRequestThreadQueue::Batch::insert passed null");
174  NS_IF_ADDREF(aRequestItem);
175  return mRequestItems.insert(aIter, aRequestItem);
176  }
180  template <class T>
181  void sort(T aComparer)
182  {
183  std::sort(mRequestItems.begin(), mRequestItems.end(), aComparer);
184  RecalcBatchStats();
185  }
186 
191  sbRequestItem * operator [](int aIndex) const
192  {
193  const const_iterator end = mRequestItems.end();
194  const_iterator iter = mRequestItems.begin();
195  while (aIndex-- > 0 && iter != end) ++iter;
196  if (iter == end) {
197  return nsnull;
198  }
199  return *iter;
200  }
201 
206  void clear();
207  private:
208  RequestItems mRequestItems;
209  PRUint32 mCountableItems;
210  PRUint32 mRequestType;
211 
212  void RecalcBatchStats();
213  };
214 
219  virtual ~sbRequestThreadQueue();
220 
221  enum {
225  USER_REQUEST_TYPES = 0x20000000,
226 
231 
236 
242  };
246  nsresult Start();
247 
254  nsresult Stop();
255 
259  nsresult BatchBegin();
260 
264  nsresult BatchEnd();
265 
271  nsresult PushRequest(sbRequestItem * aRequestItem);
272 
279  nsresult PopBatch(Batch & aBatch);
280 
285  nsresult ClearRequests();
286 
291  nsresult CancelRequests();
292 
301 
305  bool IsHandlingRequests() const {
306  NS_ENSURE_TRUE(mLock, false);
307  nsAutoLock lock(mLock);
308 
309  return mIsHandlingRequests;
310  }
311 
316  bool IsRequestAbortActive() const
317  {
318  nsAutoMonitor monitor(mStopWaitMonitor);
319  return mAbortRequests;
320  }
321 
329  PRMonitor * GetStopWaitMonitor() const
330  {
331  return mStopWaitMonitor;
332  }
333 
334 protected:
369  PRLock * mLock;
370 
374  PRInt32 mBatchDepth;
375 
379  PRMonitor* mStopWaitMonitor;
380 
381 protected:
387 
392 
399  nsresult ClearRequestsNoLock(Batch & aRequests);
400 
404  virtual void CompleteRequests()
405  {
406  nsAutoLock lock(mLock);
407  NS_ASSERTION(mIsHandlingRequests,
408  "CompleteRequests called while no requests pending");
409  mIsHandlingRequests = false;
410  nsAutoMonitor monitor(mStopWaitMonitor);
411  mAbortRequests = false;
412  }
413 
419 
424 
425 private:
429  typedef std::deque<sbRequestItem *> RequestQueue;
430 
436  RequestQueue mRequestQueue;
437 
441  nsCOMPtr<nsIThread> mThread;
442 
446  nsCOMPtr<nsIRunnable> mReqAddedEvent;
447 
451  PRInt32 mCurrentBatchId;
452 
458  nsCOMPtr<nsIRunnable> mShutdownAction;
459 
465  nsresult FindDuplicateRequest(sbRequestItem * aItem, bool &aIsDuplicate);
466 
470  nsresult ProcessRequest();
471 
476  nsresult ThreadShutdownAction(int);
477 
481  nsAutoRefCnt mRefCnt;
482 
487  bool StartRequests()
488  {
489  nsAutoLock lock(mLock);
490  const bool isHandlingRequests = mIsHandlingRequests;
491  mIsHandlingRequests = true;
492  return isHandlingRequests;
493  }
494 
495  nsresult PushRequestInternal(sbRequestItem * aRequestItem);
496 
497  // Private interface derive classes must implement
501  virtual nsresult OnThreadStart() { return NS_OK; };
502 
506  virtual nsresult OnThreadStop() { return NS_OK; }
507 
514  virtual nsresult IsDuplicateRequest(sbRequestItem * aItem1,
515  sbRequestItem * aItem2,
516  bool & aIsDuplicate,
517  bool & aContinue)
518  {
519  aIsDuplicate = false;
520  aContinue = true;
521  return NS_OK;
522  }
523 
528  virtual nsresult ProcessBatch(Batch & aBatch) = 0;
529 
534  virtual nsresult CleanupBatch(Batch & aBatch)
535  {
536  return NS_OK;
537  }
538 
539  // Friend declarations
540 
544  friend class sbRTQAddedEvent;
549  friend class sbRTQIsBatchable;
550 
555  friend class sbAutoRequestHandling;
556 };
557 
558 
559 
560 #endif
PRMonitor * GetStopWaitMonitor() const
return NS_OK
iterator insert(iterator aIter, sbRequestItem *aRequestItem)
sbRequestItem * operator[](int aIndex) const
RequestItems::size_type size_type
virtual void CompleteRequests()
bool IsRequestAbortActive() const
RequestItems::reference reference
const_iterator end() const
RequestItems::const_iterator const_iterator
nsresult PopBatch(Batch &aBatch)
nsresult ClearRequestsNoLock(Batch &aRequests)
nsresult PushRequest(sbRequestItem *aRequestItem)
RequestItems::const_reference const_reference
const_iterator begin() const
NS_IMETHOD_(nsrefcnt) AddRef(void)
bool IsHandlingRequests() const
void push_back(sbRequestItem *aItem)
RequestItems::iterator iterator