Home | History | Annotate | Download | only in base
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
     18 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
     19 
     20 #include <functional>
     21 
     22 #include "perfetto/base/build_config.h"
     23 #include "perfetto/base/utils.h"
     24 #include "perfetto/base/watchdog.h"
     25 
     26 namespace perfetto {
     27 namespace base {
     28 
     29 // Maximum time a single task can take in a TaskRunner before the
     30 // program suicides.
     31 constexpr int64_t kWatchdogMillis = 30000;  // 30s
     32 
     33 // A generic interface to allow the library clients to interleave the execution
     34 // of the tracing internals in their runtime environment.
     35 // The expectation is that all tasks, which are queued either via PostTask() or
     36 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
     37 // same thread, or on a thread pool that gives sequencing guarantees).
     38 //
     39 // Tasks are never executed synchronously inside PostTask and there is a full
     40 // memory barrier between tasks.
     41 //
     42 // All methods of this interface can be called from any thread.
     43 class TaskRunner {
     44  public:
     45   virtual ~TaskRunner();
     46 
     47   // Schedule a task for immediate execution. Immediate tasks are always
     48   // executed in the order they are posted. Can be called from any thread.
     49   virtual void PostTask(std::function<void()>) = 0;
     50 
     51   // Schedule a task for execution after |delay_ms|. Note that there is no
     52   // strict ordering guarantee between immediate and delayed tasks. Can be
     53   // called from any thread.
     54   virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
     55 
     56   // Schedule a task to run when |fd| becomes readable. The same |fd| can only
     57   // be monitored by one function. Note that this function only needs to be
     58   // implemented on platforms where the built-in ipc framework is used. Can be
     59   // called from any thread.
     60   // TODO(skyostil): Refactor this out of the shared interface.
     61   virtual void AddFileDescriptorWatch(int fd, std::function<void()>) = 0;
     62 
     63   // Remove a previously scheduled watch for |fd|. If this is run on the target
     64   // thread of this TaskRunner, guarantees that the task registered to this fd
     65   // will not be executed after this function call. Can be called from any
     66   // thread.
     67   virtual void RemoveFileDescriptorWatch(int fd) = 0;
     68 
     69  protected:
     70   static void RunTask(const std::function<void()>& task) {
     71     Watchdog::Timer handle =
     72         base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
     73     task();
     74   }
     75 };
     76 
     77 }  // namespace base
     78 }  // namespace perfetto
     79 
     80 #endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
     81