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 BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/alias.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): Investigate whether it's possible to just have
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SequencedTaskRunner use these helpers (instead of MessageLoop).
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then we can just move these to sequenced_task_runner.h.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tracked_objects {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Location;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace subtle {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, class R> class DeleteHelperInternal;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, class R> class ReleaseHelperInternal;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Template helpers which use function indirection to erase T from the
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function signature while still remembering it so we can call the
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// correct destructor/release function.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use this trick so we don't need to include bind.h in a header
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file like sequenced_task_runner.h. We also wrap the helpers in a
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// templated class to make it easier for users of DeleteSoon to
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// declare the helper as a friend.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeleteHelper {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T2, class R> friend class subtle::DeleteHelperInternal;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DoDelete(const void* object) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete reinterpret_cast<const T*>(object);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteHelper);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReleaseHelper {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T2, class R> friend class subtle::ReleaseHelperInternal;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DoRelease(const void* object) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<const T*>(object)->Release();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ReleaseHelper);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace subtle {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An internal SequencedTaskRunner-like class helper for DeleteHelper
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and ReleaseHelper.  We don't want to expose the Do*() functions
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directly directly since the void* argument makes it possible to
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pass/ an object of the wrong type to delete.  Instead, we force
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callers to go through these internal helpers for type
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// safety. SequencedTaskRunner-like classes which expose DeleteSoon or
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReleaseSoon methods should friend the appropriate helper and
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implement a corresponding *Internal method with the following
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// signature:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bool(const tracked_objects::Location&,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      void(*function)(const void*),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      void* object)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An implementation of this function should simply create a
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::Closure from (function, object) and return the result of
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// posting the task.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, class ReturnType>
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeleteHelperInternal {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class SequencedTaskRunnerType>
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ReturnType DeleteViaSequencedTaskRunner(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SequencedTaskRunnerType* sequenced_task_runner,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const T* object) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sequenced_task_runner->DeleteSoonInternal(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        from_here, &DeleteHelper<T>::DoDelete, object);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeleteHelperInternal);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, class ReturnType>
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReleaseHelperInternal {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class SequencedTaskRunnerType>
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ReturnType ReleaseViaSequencedTaskRunner(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SequencedTaskRunnerType* sequenced_task_runner,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const tracked_objects::Location& from_here,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const T* object) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sequenced_task_runner->ReleaseSoonInternal(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        from_here, &ReleaseHelper<T>::DoRelease, object);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ReleaseHelperInternal);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace subtle
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_
114