RuntimeService.java 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /** Copyright (c) 2012-2015 committers of YAKINDU and others.
  2. All rights reserved. This program and the accompanying materials
  3. are made available under the terms of the Eclipse Public License v1.0
  4. which accompanies this distribution, and is available at
  5. http://www.eclipse.org/legal/epl-v10.html
  6. Contributors:
  7. committers of YAKINDU - initial API and implementation
  8. � */
  9. package traffic.light;
  10. import java.util.HashMap;
  11. import java.util.LinkedList;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.Timer;
  15. import java.util.TimerTask;
  16. import java.util.concurrent.locks.ReentrantReadWriteLock;
  17. /**
  18. * Runtime service for state machines to execute a run to completion step
  19. * periodically.
  20. *
  21. */
  22. public class RuntimeService {
  23. private static RuntimeService runtimeService;
  24. private Timer timer = null;
  25. private Map<Long, StatemachineTimerTask> timerTasks = new HashMap<Long, StatemachineTimerTask>();
  26. private class StatemachineTimerTask extends TimerTask {
  27. private List<IStatemachine> statemachineList = new LinkedList<IStatemachine>();
  28. private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  29. private boolean isPaused = false;
  30. @Override
  31. public void run() {
  32. lock.readLock().lock();
  33. if (!isPaused) {
  34. for (IStatemachine statemachine : statemachineList) {
  35. statemachine.runCycle();
  36. }
  37. }
  38. lock.readLock().unlock();
  39. }
  40. /**
  41. * Adds the given state machine to the TimerTask.
  42. *
  43. * @param statemachine
  44. * @return {@code true} if state machine is added properly.
  45. */
  46. public boolean addStatemachine(IStatemachine statemachine) {
  47. lock.writeLock().lock();
  48. boolean ret = statemachineList.add(statemachine);
  49. lock.writeLock().unlock();
  50. return ret;
  51. }
  52. /**
  53. * Removes the given state machine from the TimerTask.
  54. *
  55. * @param statemachine
  56. * @return {@code true} if state machine is removed properly.
  57. */
  58. public boolean removeStatemachine(IStatemachine statemachine) {
  59. lock.writeLock().lock();
  60. boolean ret = statemachineList.remove(statemachine);
  61. lock.writeLock().unlock();
  62. return ret;
  63. }
  64. public void pause() {
  65. isPaused = true;
  66. }
  67. public void resume() {
  68. isPaused = false;
  69. }
  70. }
  71. private RuntimeService() {
  72. // Not intended to be instantiated.
  73. }
  74. /**
  75. * Returns the {@code RuntimeService} instance as singleton.
  76. *
  77. * @return The singleton {@code RuntimeService} instance
  78. */
  79. public static RuntimeService getInstance() {
  80. if (runtimeService == null) {
  81. runtimeService = new RuntimeService();
  82. }
  83. return runtimeService;
  84. }
  85. /**
  86. * Registers an {@link IStatemachine} for scheduled fixed rate execution
  87. *
  88. * @param statemachine
  89. * - The state machine to execute
  90. * @param cyclePeriod
  91. * - the fixed rate cycle period for scheduling
  92. * @return {@code true} if state machine is added properly.
  93. */
  94. public boolean registerStatemachine(IStatemachine statemachine,
  95. long cyclePeriod) {
  96. if (timerTasks.containsKey(cyclePeriod)) {
  97. // TimerTask for cycle time already existing -> add state machine
  98. return timerTasks.get(cyclePeriod).addStatemachine(statemachine);
  99. } else {
  100. // Create new TimerTask for cycle period and add state machine
  101. StatemachineTimerTask timerTask = new StatemachineTimerTask();
  102. timerTasks.put(cyclePeriod, timerTask);
  103. boolean ret = timerTask.addStatemachine(statemachine);
  104. // Create a new Timer instance if runtime service was cancelled
  105. // before
  106. if (timer == null) {
  107. timer = new Timer();
  108. }
  109. timer.scheduleAtFixedRate(timerTask, 0, cyclePeriod);
  110. return ret;
  111. }
  112. }
  113. /**
  114. * Removes the given state machine from runtime service.
  115. *
  116. * @param statemachine
  117. * - the state machine to be removed
  118. * @param cyclePeriod
  119. * - the scheduling cycle period of the state machine
  120. * @return {@code true} if state machine is removed properly.
  121. */
  122. public boolean unregisterStatemachine(IStatemachine statemachine,
  123. long cyclePeriod) {
  124. if (timerTasks.containsKey(cyclePeriod)) {
  125. boolean ret = timerTasks.get(cyclePeriod).removeStatemachine(
  126. statemachine);
  127. return ret;
  128. }
  129. return false;
  130. }
  131. /**
  132. * Cancels the execution of state machines for the given cycle period. This
  133. * stops the execution of state machines which are registered for the given
  134. * cycle period and cancels the executing {@link TimerTask}.
  135. *
  136. * @return {@code true} if poperly cancelled
  137. */
  138. public boolean cancelAll(long cyclePeriod) {
  139. if (timer != null && timerTasks.containsKey(cyclePeriod)) {
  140. TimerTask task = timerTasks.get(cyclePeriod);
  141. task.cancel();
  142. timer.purge();
  143. timerTasks.remove(cyclePeriod);
  144. return true;
  145. }
  146. return false;
  147. }
  148. /**
  149. * Pauses the execution of all state machines which are registered for the
  150. * given cyclePeriod.
  151. *
  152. * @param cyclePeriod
  153. * @return {@code true} if properly paused
  154. *
  155. */
  156. public boolean pauseAll(long cyclePeriod) {
  157. if (timerTasks.containsKey(cyclePeriod)) {
  158. timerTasks.get(cyclePeriod).pause();
  159. return true;
  160. }
  161. return false;
  162. }
  163. /**
  164. * Resumes the execution of all state machines which are registered for the
  165. * given cyclePeriod.
  166. *
  167. * @param cyclePeriod
  168. * @return {@code true} if properly resumed
  169. *
  170. */
  171. public boolean resumeAll(long cyclePeriod) {
  172. if (timerTasks.containsKey(cyclePeriod)) {
  173. timerTasks.get(cyclePeriod).resume();
  174. return true;
  175. }
  176. return false;
  177. }
  178. /**
  179. * Cancels the execution of all registered state machines. This cancels the
  180. * executing {@link Timer} freeing all allocated resources and terminates
  181. * all existing execution threads.
  182. */
  183. public void cancelTimer() {
  184. if (timer != null) {
  185. timer.cancel();
  186. timer.purge();
  187. timerTasks.clear();
  188. timer = null;
  189. }
  190. }
  191. }