blob: d321254e17f2fc82ed4a58d5a0fbf605ce524586 [file] [log] [blame]
Andreas Gampe04bbb5b2017-01-19 17:49:03 +00001/*
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 ART_RUNTIME_RUNTIME_CALLBACKS_H_
18#define ART_RUNTIME_RUNTIME_CALLBACKS_H_
19
20#include <vector>
21
22#include "base/macros.h"
23#include "base/mutex.h"
Alex Lightb0f11922017-01-23 14:25:17 -080024#include "dex_file.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080025#include "handle.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000026
27namespace art {
28
Andreas Gampe0f01b582017-01-18 15:22:37 -080029namespace mirror {
30class Class;
Alex Lightb0f11922017-01-23 14:25:17 -080031class ClassLoader;
Andreas Gampe0f01b582017-01-18 15:22:37 -080032} // namespace mirror
33
34class ClassLoadCallback;
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000035class Thread;
36class ThreadLifecycleCallback;
37
38// Note: RuntimeCallbacks uses the mutator lock to synchronize the callback lists. A thread must
39// hold the exclusive lock to add or remove a listener. A thread must hold the shared lock
40// to dispatch an event. This setup is chosen as some clients may want to suspend the
41// dispatching thread or all threads.
42//
43// To make this safe, the following restrictions apply:
44// * Only the owner of a listener may ever add or remove said listener.
45// * A listener must never add or remove itself or any other listener while running.
46// * It is the responsibility of the owner to not remove the listener while it is running
47// (and suspended).
48//
49// The simplest way to satisfy these restrictions is to never remove a listener, and to do
50// any state checking (is the listener enabled) in the listener itself. For an example, see
51// Dbg.
52
Andreas Gampea5814f92017-01-18 21:43:16 -080053class RuntimeSigQuitCallback {
54 public:
55 virtual ~RuntimeSigQuitCallback() {}
56
57 virtual void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
58};
59
Andreas Gampe48864112017-01-19 17:23:17 -080060class RuntimePhaseCallback {
61 public:
62 enum RuntimePhase {
Andreas Gampe96eca782017-01-19 19:45:30 -080063 kInitialAgents, // Initial agent loading is done.
64 kStart, // The runtime is started.
65 kInit, // The runtime is initialized (and will run user code soon).
66 kDeath, // The runtime just died.
Andreas Gampe48864112017-01-19 17:23:17 -080067 };
68
69 virtual ~RuntimePhaseCallback() {}
70
71 virtual void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
72};
73
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000074class RuntimeCallbacks {
75 public:
Andreas Gampe0f01b582017-01-18 15:22:37 -080076 void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
77 void RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000078
Andreas Gampe0f01b582017-01-18 15:22:37 -080079 void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
80 void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
81
82 void AddClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
83 void RemoveClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
84
85 void ClassLoad(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
86 void ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass)
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000087 REQUIRES_SHARED(Locks::mutator_lock_);
88
Andreas Gampea5814f92017-01-18 21:43:16 -080089 void AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
90 REQUIRES(Locks::mutator_lock_);
91 void RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
92 REQUIRES(Locks::mutator_lock_);
93
94 void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_);
95
Andreas Gampe48864112017-01-19 17:23:17 -080096 void AddRuntimePhaseCallback(RuntimePhaseCallback* cb)
97 REQUIRES(Locks::mutator_lock_);
98 void RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb)
99 REQUIRES(Locks::mutator_lock_);
100
101 void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)
102 REQUIRES_SHARED(Locks::mutator_lock_);
103
Alex Lightb0f11922017-01-23 14:25:17 -0800104 void ClassPreDefine(const char* descriptor,
105 Handle<mirror::Class> temp_class,
106 Handle<mirror::ClassLoader> loader,
107 const DexFile& initial_dex_file,
108 const DexFile::ClassDef& initial_class_def,
109 /*out*/DexFile const** final_dex_file,
110 /*out*/DexFile::ClassDef const** final_class_def)
111 REQUIRES_SHARED(Locks::mutator_lock_);
112
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000113 private:
114 std::vector<ThreadLifecycleCallback*> thread_callbacks_
115 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe0f01b582017-01-18 15:22:37 -0800116 std::vector<ClassLoadCallback*> class_callbacks_
117 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampea5814f92017-01-18 21:43:16 -0800118 std::vector<RuntimeSigQuitCallback*> sigquit_callbacks_
119 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe48864112017-01-19 17:23:17 -0800120 std::vector<RuntimePhaseCallback*> phase_callbacks_
121 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000122};
123
124} // namespace art
125
126#endif // ART_RUNTIME_RUNTIME_CALLBACKS_H_