Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MEDIA_BASE_SERIAL_RUNNER_H_
      6 #define MEDIA_BASE_SERIAL_RUNNER_H_
      7 
      8 #include <queue>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "media/base/media_export.h"
     15 #include "media/base/pipeline_status.h"
     16 
     17 namespace base {
     18 class SingleThreadTaskRunner;
     19 }
     20 
     21 namespace media {
     22 
     23 // Runs a series of bound functions accepting Closures or PipelineStatusCB.
     24 // SerialRunner doesn't use regular Closure/PipelineStatusCBs as it late binds
     25 // the completion callback as the series progresses.
     26 class MEDIA_EXPORT SerialRunner {
     27  public:
     28   typedef base::Callback<void(const base::Closure&)> BoundClosure;
     29   typedef base::Callback<void(const PipelineStatusCB&)> BoundPipelineStatusCB;
     30 
     31   // Serial queue of bound functions to run.
     32   class MEDIA_EXPORT Queue {
     33    public:
     34     Queue();
     35     ~Queue();
     36 
     37     void Push(const base::Closure& closure);
     38     void Push(const BoundClosure& bound_fn);
     39     void Push(const BoundPipelineStatusCB& bound_fn);
     40 
     41    private:
     42     friend class SerialRunner;
     43 
     44     BoundPipelineStatusCB Pop();
     45     bool empty();
     46 
     47     std::queue<BoundPipelineStatusCB> bound_fns_;
     48   };
     49 
     50   // Executes the bound functions in series, executing |done_cb| when finished.
     51   //
     52   // All bound functions are executed on the thread that Run() is called on,
     53   // including |done_cb|.
     54   //
     55   // To eliminate an unnecessary posted task, the first function is executed
     56   // immediately on the caller's stack. It is *strongly advised* to ensure
     57   // the calling code does no more work after the call to Run().
     58   //
     59   // In all cases, |done_cb| is guaranteed to execute on a separate calling
     60   // stack.
     61   //
     62   // Deleting the object will prevent execution of any unstarted bound
     63   // functions, including |done_cb|.
     64   static scoped_ptr<SerialRunner> Run(
     65       const Queue& bound_fns, const PipelineStatusCB& done_cb);
     66 
     67  private:
     68   friend struct base::DefaultDeleter<SerialRunner>;
     69 
     70   SerialRunner(const Queue& bound_fns, const PipelineStatusCB& done_cb);
     71   ~SerialRunner();
     72 
     73   void RunNextInSeries(PipelineStatus last_status);
     74 
     75   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
     76   Queue bound_fns_;
     77   PipelineStatusCB done_cb_;
     78 
     79   // NOTE: Weak pointers must be invalidated before all other member variables.
     80   base::WeakPtrFactory<SerialRunner> weak_factory_;
     81 
     82   DISALLOW_COPY_AND_ASSIGN(SerialRunner);
     83 };
     84 
     85 }  // namespace media
     86 
     87 #endif  // MEDIA_BASE_SERIAL_RUNNER_H_
     88