void init(DataInputStream stream) throws IOException { long start = System.currentTimeMillis(); // copy over data first so we are not blocked while reading data byte[] bytes = new byte[stream.readInt()]; stream.readFully(bytes); DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes)); long read = System.currentTimeMillis(); // we have all the data in the array now, read from that... synchronized (this) { long locked = System.currentTimeMillis(); if (initialized) { // already initialized, ignore return; } logger.debug("reading bootstrap state"); time = in.readInt(); members.init(in); long membersDone = System.currentTimeMillis(); elections.init(in); int nrOfSignals = in.readInt(); if (nrOfSignals < 0) { throw new IOException("negative number of signals"); } ArrayList<Event> signals = new ArrayList<Event>(); for (int i = 0; i < nrOfSignals; i++) { signals.add(new Event(in)); } closed = in.readBoolean(); if (closed) { closeEvent = new Event(in); } terminated = in.readBoolean(); if (terminated) { terminateEvent = new Event(in); } // Create list of "old" events SortedSet<Event> events = new TreeSet<Event>(); events.addAll(members.getJoinEvents()); events.addAll(elections.getEvents()); events.addAll(signals); if (closed) { events.add(closeEvent); } if (terminated) { events.add(terminateEvent); } long used = System.currentTimeMillis(); // pass old events to the registry // CALLS REGISTRY WHILE POOL IS LOCKED! for (Event event : events) { registry.handleEvent(event); } long handled = System.currentTimeMillis(); initialized = true; notifyAll(); if (statistics != null) { statistics.newPoolSize(members.size()); } long statted = System.currentTimeMillis(); logger.info( "pool init, read = " + (read - start) + ", locked = " + (locked - read) + ", membersDone = " + (membersDone - locked) + ", used = " + (used - membersDone) + ", handled = " + (handled - used) + ", statted = " + (statted - handled)); } handleEvents(); logger.debug("bootstrap complete"); }