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 MessageLoopProxy;
     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 BoundClosure& bound_fn);
     38     void Push(const BoundPipelineStatusCB& bound_fn);
     39 
     40    private:
     41     friend class SerialRunner;
     42 
     43     BoundPipelineStatusCB Pop();
     44     bool empty();
     45 
     46     std::queue<BoundPipelineStatusCB> bound_fns_;
     47   };
     48 
     49   // Executes the bound functions in series, executing |done_cb| when finished.
     50   //
     51   // All bound functions are executed on the thread that Run() is called on,
     52   // including |done_cb|.
     53   //
     54   // To eliminate an unnecessary posted task, the first function is executed
     55   // immediately on the caller's stack. It is *strongly advised* to ensure
     56   // the calling code does no more work after the call to Run().
     57   //
     58   // In all cases, |done_cb| is guaranteed to execute on a separate calling
     59   // stack.
     60   //
     61   // Deleting the object will prevent execution of any unstarted bound
     62   // functions, including |done_cb|.
     63   static scoped_ptr<SerialRunner> Run(
     64       const Queue& bound_fns, const PipelineStatusCB& done_cb);
     65 
     66  private:
     67   friend struct base::DefaultDeleter<SerialRunner>;
     68 
     69   SerialRunner(const Queue& bound_fns, const PipelineStatusCB& done_cb);
     70   ~SerialRunner();
     71 
     72   void RunNextInSeries(PipelineStatus last_status);
     73 
     74   base::WeakPtrFactory<SerialRunner> weak_this_;
     75   scoped_refptr<base::MessageLoopProxy> message_loop_;
     76   Queue bound_fns_;
     77   PipelineStatusCB done_cb_;
     78 
     79   DISALLOW_COPY_AND_ASSIGN(SerialRunner);
     80 };
     81 
     82 }  // namespace media
     83 
     84 #endif  // MEDIA_BASE_SERIAL_RUNNER_H_
     85