Skip to content

Commit 79b7909

Browse files
committed
8255980: G1 Service thread register_task can be used after shutdown
Reviewed-by: tschatzl, ayang
1 parent dd8e4ff commit 79b7909

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

src/hotspot/share/gc/g1/g1ServiceThread.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,30 @@ G1ServiceThread::G1ServiceThread() :
176176
true,
177177
Monitor::_safepoint_check_never),
178178
_task_queue(),
179+
_remset_task(new G1RemSetSamplingTask("Remembered Set Sampling Task")),
180+
_periodic_gc_task(new G1PeriodicGCTask("Periodic GC Task")),
179181
_vtime_accum(0) {
180182
set_name("G1 Service");
181183
create_and_start();
182184
}
183185

186+
G1ServiceThread::~G1ServiceThread() {
187+
delete _remset_task;
188+
delete _periodic_gc_task;
189+
}
190+
184191
void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay) {
185192
guarantee(!task->is_registered(), "Task already registered");
186193
guarantee(task->next() == NULL, "Task already in queue");
187194

195+
// Make sure the service thread is still up and running, there is a race
196+
// during shutdown where the service thread has been stopped, but other
197+
// GC threads might still be running and trying to add tasks.
198+
if (has_terminated()) {
199+
log_debug(gc, task)("G1 Service Thread (%s) (terminated)", task->name());
200+
return;
201+
}
202+
188203
log_debug(gc, task)("G1 Service Thread (%s) (register)", task->name());
189204

190205
// Associate the task with the service thread.
@@ -272,13 +287,9 @@ void G1ServiceThread::run_task(G1ServiceTask* task) {
272287
void G1ServiceThread::run_service() {
273288
double vtime_start = os::elapsedVTime();
274289

275-
// Setup the tasks handeled by the service thread and
276-
// add them to the task list.
277-
G1PeriodicGCTask gc_task("Periodic GC Task");
278-
register_task(&gc_task);
279-
280-
G1RemSetSamplingTask remset_task("Remembered Set Sampling Task");
281-
register_task(&remset_task);
290+
// Register the tasks handled by the service thread.
291+
register_task(_periodic_gc_task);
292+
register_task(_remset_task);
282293

283294
while (!should_terminate()) {
284295
G1ServiceTask* task = pop_due_task();
@@ -293,6 +304,8 @@ void G1ServiceThread::run_service() {
293304
}
294305
sleep_before_next_cycle();
295306
}
307+
308+
log_debug(gc, task)("G1 Service Thread (stopping)");
296309
}
297310

298311
void G1ServiceThread::stop_service() {

src/hotspot/share/gc/g1/g1ServiceThread.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "gc/shared/concurrentGCThread.hpp"
2929
#include "runtime/mutex.hpp"
3030

31+
class G1PeriodicGCTask;
32+
class G1RemSetSamplingTask;
3133
class G1ServiceTaskQueue;
3234
class G1ServiceThread;
3335

@@ -103,6 +105,9 @@ class G1ServiceThread: public ConcurrentGCThread {
103105
Monitor _monitor;
104106
G1ServiceTaskQueue _task_queue;
105107

108+
G1RemSetSamplingTask* _remset_task;
109+
G1PeriodicGCTask* _periodic_gc_task;
110+
106111
double _vtime_accum; // Accumulated virtual time.
107112

108113
void run_service();
@@ -122,6 +127,8 @@ class G1ServiceThread: public ConcurrentGCThread {
122127

123128
public:
124129
G1ServiceThread();
130+
~G1ServiceThread();
131+
125132
double vtime_accum() { return _vtime_accum; }
126133
// Register a task with the service thread and schedule it. If
127134
// no delay is specified the task is scheduled to run directly.

0 commit comments

Comments
 (0)