safe executor service creation
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
c6948b89ce
commit
7ad7a0c477
@ -1796,6 +1796,7 @@ Support for freeing shaders
|
|||||||
Utilities to free all of a type of resource
|
Utilities to free all of a type of resource
|
||||||
Slowdown entity tests to prevent VSCode from exploding when running tests
|
Slowdown entity tests to prevent VSCode from exploding when running tests
|
||||||
Fix static state caching between tests in visual shader construction
|
Fix static state caching between tests in visual shader construction
|
||||||
|
Safe executor service creation in non final static contexts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,22 @@ public class ImGuiRenderer {
|
|||||||
}
|
}
|
||||||
ImGui.unindent();
|
ImGui.unindent();
|
||||||
}
|
}
|
||||||
|
if(ImGui.collapsingHeader("Debug Toggles")){
|
||||||
|
ImGui.indent();
|
||||||
|
if(ImGui.button("Draw Client Hitboxes")){
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresClient(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresClient());
|
||||||
|
}
|
||||||
|
if(ImGui.button("Draw Server Hitboxes")){
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresServer(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresServer());
|
||||||
|
}
|
||||||
|
if(ImGui.button("Draw Physics Objects")){
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawPhysicsObjects(!Globals.userSettings.graphicsDebugDrawPhysicsObjects());
|
||||||
|
}
|
||||||
|
if(ImGui.button("Draw Grid Alignment Data")){
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawGridAlignment(!Globals.userSettings.getGraphicsDebugDrawGridAlignment());
|
||||||
|
}
|
||||||
|
ImGui.unindent();
|
||||||
|
}
|
||||||
if(ImGui.collapsingHeader("OpenGL Details")){
|
if(ImGui.collapsingHeader("OpenGL Details")){
|
||||||
ImGui.text("GL_MAX_TEXTURE_IMAGE_UNITS: " + Globals.renderingEngine.getOpenGLContext().getMaxTextureImageUnits());
|
ImGui.text("GL_MAX_TEXTURE_IMAGE_UNITS: " + Globals.renderingEngine.getOpenGLContext().getMaxTextureImageUnits());
|
||||||
ImGui.text("GL_MAX_TEXTURE_SIZE: " + Globals.renderingEngine.getOpenGLContext().getMaxTextureSize());
|
ImGui.text("GL_MAX_TEXTURE_SIZE: " + Globals.renderingEngine.getOpenGLContext().getMaxTextureSize());
|
||||||
|
|||||||
@ -3,8 +3,10 @@ package electrosphere.engine.threads;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import electrosphere.client.terrain.foliage.FoliageModel;
|
import electrosphere.client.terrain.foliage.FoliageModel;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
@ -13,7 +15,6 @@ import electrosphere.engine.threads.LabeledThread.ThreadLabel;
|
|||||||
import electrosphere.entity.types.terrain.BlockChunkEntity;
|
import electrosphere.entity.types.terrain.BlockChunkEntity;
|
||||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||||
import electrosphere.server.ai.services.PathfindingService;
|
import electrosphere.server.ai.services.PathfindingService;
|
||||||
import electrosphere.server.datacell.gridded.GriddedDataCellLoaderService;
|
|
||||||
import electrosphere.util.CodeUtils;
|
import electrosphere.util.CodeUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,24 +22,37 @@ import electrosphere.util.CodeUtils;
|
|||||||
*/
|
*/
|
||||||
public class ThreadManager {
|
public class ThreadManager {
|
||||||
|
|
||||||
//Threadsafes the manager
|
/**
|
||||||
Semaphore threadLock;
|
* Threadsafes the manager
|
||||||
|
*/
|
||||||
|
private ReentrantLock threadLock;
|
||||||
|
|
||||||
//All threads that are actively running
|
/**
|
||||||
|
* All threads that are actively running
|
||||||
|
*/
|
||||||
private List<LabeledThread> activeThreads;
|
private List<LabeledThread> activeThreads;
|
||||||
|
|
||||||
//All loading threads that are actively running
|
/**
|
||||||
|
* All loading threads that are actively running
|
||||||
|
*/
|
||||||
private List<LoadingThread> loadingThreads;
|
private List<LoadingThread> loadingThreads;
|
||||||
|
|
||||||
//Used by main thread to alert other threads whether they should keep running or not
|
/**
|
||||||
|
* Used by main thread to alert other threads whether they should keep running or not
|
||||||
|
*/
|
||||||
private boolean shouldKeepRunning;
|
private boolean shouldKeepRunning;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks all executors created
|
||||||
|
*/
|
||||||
|
private static List<ExecutorService> executors = new LinkedList<ExecutorService>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the thread manager
|
* Initializes the thread manager
|
||||||
*/
|
*/
|
||||||
public void init(){
|
public void init(){
|
||||||
threadLock = new Semaphore(1);
|
threadLock = new ReentrantLock();
|
||||||
activeThreads = new LinkedList<LabeledThread>();
|
activeThreads = new LinkedList<LabeledThread>();
|
||||||
loadingThreads = new LinkedList<LoadingThread>();
|
loadingThreads = new LinkedList<LoadingThread>();
|
||||||
shouldKeepRunning = true;
|
shouldKeepRunning = true;
|
||||||
@ -48,7 +62,7 @@ public class ThreadManager {
|
|||||||
* Updates what threads are being tracked
|
* Updates what threads are being tracked
|
||||||
*/
|
*/
|
||||||
public void update(){
|
public void update(){
|
||||||
threadLock.acquireUninterruptibly();
|
threadLock.lock();
|
||||||
//
|
//
|
||||||
//remove loading threads
|
//remove loading threads
|
||||||
List<Thread> threadsToRemove = new LinkedList<Thread>();
|
List<Thread> threadsToRemove = new LinkedList<Thread>();
|
||||||
@ -61,7 +75,7 @@ public class ThreadManager {
|
|||||||
loadingThreads.remove(thread);
|
loadingThreads.remove(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
threadLock.release();
|
threadLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,10 +83,10 @@ public class ThreadManager {
|
|||||||
* @param thread The thread to start
|
* @param thread The thread to start
|
||||||
*/
|
*/
|
||||||
public void start(ThreadLabel label, Thread thread){
|
public void start(ThreadLabel label, Thread thread){
|
||||||
threadLock.acquireUninterruptibly();
|
threadLock.lock();
|
||||||
activeThreads.add(new LabeledThread(label, thread));
|
activeThreads.add(new LabeledThread(label, thread));
|
||||||
thread.start();
|
thread.start();
|
||||||
threadLock.release();
|
threadLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,11 +94,11 @@ public class ThreadManager {
|
|||||||
* @param thread The loading thread to start
|
* @param thread The loading thread to start
|
||||||
*/
|
*/
|
||||||
public void start(LoadingThread thread){
|
public void start(LoadingThread thread){
|
||||||
threadLock.acquireUninterruptibly();
|
threadLock.lock();
|
||||||
activeThreads.add(new LabeledThread(ThreadLabel.LOADING, thread));
|
activeThreads.add(new LabeledThread(ThreadLabel.LOADING, thread));
|
||||||
loadingThreads.add(thread);
|
loadingThreads.add(thread);
|
||||||
thread.start();
|
thread.start();
|
||||||
threadLock.release();
|
threadLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +122,7 @@ public class ThreadManager {
|
|||||||
*/
|
*/
|
||||||
public void close(){
|
public void close(){
|
||||||
this.shouldKeepRunning = false;
|
this.shouldKeepRunning = false;
|
||||||
threadLock.acquireUninterruptibly();
|
threadLock.lock();
|
||||||
|
|
||||||
//for some reason, server must be explicitly closed
|
//for some reason, server must be explicitly closed
|
||||||
if(Globals.server != null){
|
if(Globals.server != null){
|
||||||
@ -125,9 +139,15 @@ public class ThreadManager {
|
|||||||
TerrainChunk.haltThreads();
|
TerrainChunk.haltThreads();
|
||||||
FoliageModel.haltThreads();
|
FoliageModel.haltThreads();
|
||||||
BlockChunkEntity.haltThreads();
|
BlockChunkEntity.haltThreads();
|
||||||
GriddedDataCellLoaderService.haltThreads();
|
|
||||||
PathfindingService.haltThreads();
|
PathfindingService.haltThreads();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Halt all requested executors
|
||||||
|
*/
|
||||||
|
for(ExecutorService service : executors){
|
||||||
|
service.shutdownNow();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//interrupt all threads
|
//interrupt all threads
|
||||||
for(int i = 0; i < 3; i++){
|
for(int i = 0; i < 3; i++){
|
||||||
@ -150,7 +170,7 @@ public class ThreadManager {
|
|||||||
CodeUtils.todo(e, "Handle failing to sleep while interrupting all other threads");
|
CodeUtils.todo(e, "Handle failing to sleep while interrupting all other threads");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
threadLock.release();
|
threadLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,7 +186,7 @@ public class ThreadManager {
|
|||||||
* @param label The label
|
* @param label The label
|
||||||
*/
|
*/
|
||||||
public void interruptLabel(ThreadLabel label){
|
public void interruptLabel(ThreadLabel label){
|
||||||
threadLock.acquireUninterruptibly();
|
threadLock.lock();
|
||||||
//
|
//
|
||||||
//interrupt threads
|
//interrupt threads
|
||||||
for(LabeledThread thread : activeThreads){
|
for(LabeledThread thread : activeThreads){
|
||||||
@ -174,7 +194,24 @@ public class ThreadManager {
|
|||||||
thread.getThread().interrupt();
|
thread.getThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
threadLock.release();
|
threadLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a fixed-size thread pool
|
||||||
|
* @param threads The number of threads
|
||||||
|
* @return The executor
|
||||||
|
*/
|
||||||
|
public ExecutorService requestFixedThreadPool(int threads){
|
||||||
|
if(threads < 1){
|
||||||
|
throw new Error("Requested invalid number of threads! " + threads);
|
||||||
|
}
|
||||||
|
ExecutorService rVal = null;
|
||||||
|
threadLock.lock();
|
||||||
|
rVal = Executors.newFixedThreadPool(threads);
|
||||||
|
executors.add(rVal);
|
||||||
|
threadLock.unlock();
|
||||||
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ public class GriddedDataCellLoaderService {
|
|||||||
/**
|
/**
|
||||||
* Used for loading/unloading the cells
|
* Used for loading/unloading the cells
|
||||||
*/
|
*/
|
||||||
protected static final ExecutorService ioThreadService = Executors.newFixedThreadPool(ThreadCounts.GRIDDED_DATACELL_LOADING_THREADS);
|
private ExecutorService ioThreadService = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock for structures in this service
|
* Lock for structures in this service
|
||||||
@ -37,13 +36,20 @@ public class GriddedDataCellLoaderService {
|
|||||||
*/
|
*/
|
||||||
private static final Map<Long,Runnable> jobOperationMap = new HashMap<Long,Runnable>();
|
private static final Map<Long,Runnable> jobOperationMap = new HashMap<Long,Runnable>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public GriddedDataCellLoaderService(){
|
||||||
|
this.ioThreadService = Globals.threadManager.requestFixedThreadPool(ThreadCounts.GRIDDED_DATACELL_LOADING_THREADS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues an operation that requires a read or write of a location's file data.
|
* Queues an operation that requires a read or write of a location's file data.
|
||||||
* Guarantees that all operations will be run in order without losing any work.
|
* Guarantees that all operations will be run in order without losing any work.
|
||||||
* @param key The key for the cell
|
* @param key The key for the cell
|
||||||
* @param operation The operation to perform
|
* @param operation The operation to perform
|
||||||
*/
|
*/
|
||||||
protected static void queueLocationBasedOperation(long key, Runnable operation){
|
protected void queueLocationBasedOperation(long key, Runnable operation){
|
||||||
lock.lock();
|
lock.lock();
|
||||||
//if there is a job queued and we couldn't cancel it, wait
|
//if there is a job queued and we couldn't cancel it, wait
|
||||||
Future<?> job = queuedWorkLock.get(key);
|
Future<?> job = queuedWorkLock.get(key);
|
||||||
@ -96,7 +102,7 @@ public class GriddedDataCellLoaderService {
|
|||||||
/**
|
/**
|
||||||
* Halts the threads for the data cell loader service
|
* Halts the threads for the data cell loader service
|
||||||
*/
|
*/
|
||||||
public static void haltThreads(){
|
public void haltThreads(){
|
||||||
ioThreadService.shutdownNow();
|
ioThreadService.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -76,16 +75,21 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
*/
|
*/
|
||||||
static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for generating physics chunks
|
|
||||||
*/
|
|
||||||
static final ExecutorService generationService = Executors.newFixedThreadPool(ThreadCounts.GRIDDED_DATACELL_PHYSICS_GEN_THREADS);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Big number used when scanning for a data cell to spawn a macro object within
|
* Big number used when scanning for a data cell to spawn a macro object within
|
||||||
*/
|
*/
|
||||||
static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for generating physics chunks
|
||||||
|
*/
|
||||||
|
ExecutorService generationService = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The service for loading data cells from disk
|
||||||
|
*/
|
||||||
|
GriddedDataCellLoaderService loaderService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether this manager has been flagged to unload cells or not
|
* Tracks whether this manager has been flagged to unload cells or not
|
||||||
*/
|
*/
|
||||||
@ -192,15 +196,17 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
this.serverFluidManager == null ||
|
this.serverFluidManager == null ||
|
||||||
this.serverContentManager == null
|
this.serverContentManager == null
|
||||||
){
|
){
|
||||||
throw new IllegalStateException("Tried to create a GriddedDataCellManager with invalid parameters " +
|
throw new Error("Tried to create a GriddedDataCellManager with invalid parameters " +
|
||||||
this.parent + " " +
|
this.parent + " " +
|
||||||
this.serverWorldData + " " +
|
this.serverWorldData + " " +
|
||||||
this.serverTerrainManager + " " +
|
this.serverTerrainManager + " " +
|
||||||
this.serverFluidManager + " " +
|
this.serverFluidManager + " " +
|
||||||
this.serverContentManager + " "
|
this.serverContentManager + " "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.pathfinder = new VoxelPathfinder();
|
this.pathfinder = new VoxelPathfinder();
|
||||||
|
this.loaderService = new GriddedDataCellLoaderService();
|
||||||
|
this.generationService = Globals.threadManager.requestFixedThreadPool(ThreadCounts.GRIDDED_DATACELL_PHYSICS_GEN_THREADS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -549,7 +555,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
||||||
//don't trigger the chunk to be re-created
|
//don't trigger the chunk to be re-created
|
||||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
||||||
GriddedDataCellLoaderService.queueLocationBasedOperation(key, () -> {
|
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||||
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
||||||
serverTerrainManager.savePositionToDisk(worldPos);
|
serverTerrainManager.savePositionToDisk(worldPos);
|
||||||
});
|
});
|
||||||
@ -768,7 +774,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* Because cell hasn't been registered yet, no simulation is performed until the physics is created.
|
* Because cell hasn't been registered yet, no simulation is performed until the physics is created.
|
||||||
* @param worldPos
|
* @param worldPos
|
||||||
*/
|
*/
|
||||||
private static void runPhysicsGenerationThread(
|
private void runPhysicsGenerationThread(
|
||||||
Vector3i worldPos,
|
Vector3i worldPos,
|
||||||
Long key,
|
Long key,
|
||||||
PhysicsDataCell cell,
|
PhysicsDataCell cell,
|
||||||
@ -805,7 +811,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
ServerEntityUtils.destroyEntity(blockEntity);
|
ServerEntityUtils.destroyEntity(blockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
generationService.submit(() -> {
|
this.generationService.submit(() -> {
|
||||||
try {
|
try {
|
||||||
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||||
ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES);
|
ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES);
|
||||||
@ -861,7 +867,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
|
|
||||||
Long key = this.getServerDataCellKey(localWorldPos);
|
Long key = this.getServerDataCellKey(localWorldPos);
|
||||||
//generate content
|
//generate content
|
||||||
GriddedDataCellLoaderService.queueLocationBasedOperation(key, () -> {
|
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||||
try {
|
try {
|
||||||
serverContentManager.generateContentForDataCell(parent, localWorldPos, rVal, cellKey);
|
serverContentManager.generateContentForDataCell(parent, localWorldPos, rVal, cellKey);
|
||||||
} catch(Error e){
|
} catch(Error e){
|
||||||
@ -873,7 +879,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//generates physics for the cell in a dedicated thread then finally registers
|
//generates physics for the cell in a dedicated thread then finally registers
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||||
GriddedDataCellManager.runPhysicsGenerationThread(localWorldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.cellTrackingMap,this.parent);
|
this.runPhysicsGenerationThread(localWorldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.cellTrackingMap,this.parent);
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
|
|
||||||
|
|
||||||
@ -1047,8 +1053,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* Stops the executor service
|
* Stops the executor service
|
||||||
*/
|
*/
|
||||||
public void halt(){
|
public void halt(){
|
||||||
generationService.shutdownNow();
|
this.generationService.shutdownNow();
|
||||||
GriddedDataCellLoaderService.ioThreadService.shutdownNow();
|
this.loaderService.haltThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user