15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_BASE_SERIAL_RUNNER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_BASE_SERIAL_RUNNER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/media_export.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline_status.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Runs a series of bound functions accepting Closures or PipelineStatusCB.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerialRunner doesn't use regular Closure/PipelineStatusCBs as it late binds
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the completion callback as the series progresses.
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class MEDIA_EXPORT SerialRunner {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const base::Closure&)> BoundClosure;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const PipelineStatusCB&)> BoundPipelineStatusCB;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serial queue of bound functions to run.
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  class MEDIA_EXPORT Queue {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Queue();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~Queue();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    void Push(const base::Closure& closure);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Push(const BoundClosure& bound_fn);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Push(const BoundPipelineStatusCB& bound_fn);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class SerialRunner;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BoundPipelineStatusCB Pop();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool empty();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::queue<BoundPipelineStatusCB> bound_fns_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Executes the bound functions in series, executing |done_cb| when finished.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All bound functions are executed on the thread that Run() is called on,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // including |done_cb|.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // To eliminate an unnecessary posted task, the first function is executed
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // immediately on the caller's stack. It is *strongly advised* to ensure
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // the calling code does no more work after the call to Run().
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  //
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // In all cases, |done_cb| is guaranteed to execute on a separate calling
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // stack.
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  //
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deleting the object will prevent execution of any unstarted bound
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functions, including |done_cb|.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<SerialRunner> Run(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const Queue& bound_fns, const PipelineStatusCB& done_cb);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend struct base::DefaultDeleter<SerialRunner>;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerialRunner(const Queue& bound_fns, const PipelineStatusCB& done_cb);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SerialRunner();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunNextInSeries(PipelineStatus last_status);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Queue bound_fns_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB done_cb_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<SerialRunner> weak_factory_;
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SerialRunner);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_BASE_SERIAL_RUNNER_H_
88