/** * Read the initial alarm configuration * * @throws Exception on error */ private void readConfiguration() throws Exception { // Read alarm hierarchy final BenchmarkTimer timer = new BenchmarkTimer(); final int pv_count; synchronized (this) { alarm_tree = rdb.readConfiguration(); // Determine PVs final ArrayList<AlarmPV> tmp_pv_array = new ArrayList<AlarmPV>(); findPVs(alarm_tree, tmp_pv_array); // Turn into plain array pv_list = tmp_pv_array.toArray(new AlarmPV[tmp_pv_array.size()]); tmp_pv_array.clear(); // Sort PVs by name Arrays.sort( pv_list, new Comparator<AlarmPV>() { @Override public int compare(final AlarmPV pv1, final AlarmPV pv2) { return pv1.getName().compareTo(pv2.getName()); } }); // Create hash pv_map = new HashMap<String, AlarmPV>(); for (AlarmPV pv : pv_list) pv_map.put(pv.getName(), pv); pv_count = pv_list.length; } timer.stop(); // LDAP results: Read 12614 PVs in 2.69 seconds, 4689.0 PVs/sec System.out.format( "Read %d PVs in %.2f seconds: %.1f PVs/sec\n", pv_count, timer.getSeconds(), pv_count / timer.getSeconds()); }
/** Stop PVs */ private void stopPVs() { // See deadlock comment in start() final AlarmPV pvs[]; synchronized (this) { pvs = pv_list.clone(); } for (AlarmPV pv : pvs) pv.stop(); }
/** * Set maintenance mode. * * @param maintenance_mode * @see AlarmLogic#getMaintenanceMode() */ public void setMaintenanceMode(final boolean maintenance_mode) { // Any change? if (maintenance_mode == AlarmLogic.getMaintenanceMode()) return; // Configure alarm logic AlarmLogic.setMaintenanceMode(maintenance_mode); // Send update to clients messenger.sendIdleMessage(); // Entering maintenance mode: Ack' all INVALID alarms if (maintenance_mode) { synchronized (this) { for (AlarmPV pv : pv_list) { final AlarmLogic logic = pv.getAlarmLogic(); if (logic.getAlarmState().getSeverity() == SeverityLevel.INVALID) logic.acknowledge(true); } } } }
/** * Read updated configuration for PV from RDB * * @param path_name PV name or <code>null</code> to reload complete configuration */ void updateConfig(final String path_name) throws Exception { resetNagTimer(); AlarmPV pv = null; if (path_name != null) { final String[] path = AlarmTreePath.splitPath(path_name); // Is this a PV under a different alarm tree root? if (!root_name.equals(path[0])) return; // Locate PV, assuming last path element is PV pv = findPV(path[path.length - 1]); } if (pv == null) { // Unknown PV, so this must be a new PV. Read whole config again stopPVs(); readConfiguration(); startPVs(); return; } // Known PV pv.stop(); rdb.readConfigurationUpdate(pv); pv.start(); }
/** Start PVs */ private void startPVs() { final long delay = Preferences.getPVStartDelay(); // Must not sync while calling PV, because Channel Access updates // might arrive while we're trying to start/stop channels, // and those updates will try to lock the Alarm Server, // which then results in a deadlock: // a) We lock AlarmServer, then try to call CA, // which takes internal JNI locks // b) CA takes internal locks, calls PV update callback, which // then tries to lock the AlarmServer when locating the PV by name final AlarmPV pvs[]; synchronized (this) { pvs = pv_list.clone(); } for (AlarmPV pv : pvs) { try { pv.start(); if (delay > 0) Thread.sleep(delay); } catch (Exception ex) { Activator.getLogger().log(Level.SEVERE, "Error starting PV " + pv.getName(), ex); } } }
/** * (Un-)acknowledge alarm. * * @param pv_name PV to acknowledge * @param acknowledge Acknowledge, or un-acknowledge? */ public void acknowledge(final String pv_name, final boolean acknowledge) { resetNagTimer(); final AlarmPV pv = findPV(pv_name); if (pv != null) pv.getAlarmLogic().acknowledge(acknowledge); }