Ejemplo n.º 1
1
 void start() {
   if (t == null) {
     t = new Thread(this, "UDP.OutgoingPacketHandler thread");
     t.setDaemon(true);
     t.start();
   }
 }
Ejemplo n.º 2
0
  /** Stops unicast and multicast receiver threads */
  void stopThreads() {
    Thread tmp;

    // 1. Stop the multicast receiver thread
    if (mcast_receiver != null) {
      if (mcast_receiver.isAlive()) {
        tmp = mcast_receiver;
        mcast_receiver = null;
        closeMulticastSocket(); // will cause the multicast thread to terminate
        tmp.interrupt();
        try {
          tmp.join(100);
        } catch (Exception e) {
        }
        tmp = null;
      }
      mcast_receiver = null;
    }

    // 2. Stop the unicast receiver thread
    if (ucast_receiver != null) {
      ucast_receiver.stop();
      ucast_receiver = null;
    }

    // 3. Stop the in_packet_handler thread
    if (incoming_packet_handler != null) {
      incoming_packet_handler.stop();
    }
  }
Ejemplo n.º 3
0
    /**
     * @param views Guaranteed to be non-null and to have >= 2 members, or else this thread would
     *     not be started
     */
    public synchronized void start(Map<Address, View> views) {
      if (thread == null || thread.isAlive()) {
        this.coords.clear();

        // now remove all members which don't have us in their view, so RPCs won't block (e.g.
        // FLUSH)
        // https://jira.jboss.org/browse/JGRP-1061
        sanitizeViews(views);

        // Add all different coordinators of the views into the hashmap and sets their members:
        Collection<Address> coordinators = Util.determineMergeCoords(views);
        for (Address coord : coordinators) {
          View view = views.get(coord);
          if (view != null) this.coords.put(coord, new ArrayList<Address>(view.getMembers()));
        }

        // For the merge participants which are not coordinator, we simply add them, and the
        // associated
        // membership list consists only of themselves
        Collection<Address> merge_participants = Util.determineMergeParticipants(views);
        merge_participants.removeAll(coordinators);
        for (Address merge_participant : merge_participants) {
          Collection<Address> tmp = new ArrayList<Address>();
          tmp.add(merge_participant);
          coords.putIfAbsent(merge_participant, tmp);
        }

        thread = gms.getThreadFactory().newThread(this, "MergeTask");
        thread.setDaemon(true);
        thread.start();
      }
    }
Ejemplo n.º 4
0
 public void start() {
   if (thread == null) {
     thread = new Thread(this, "UDP.UcastReceiverThread");
     thread.setDaemon(true);
     running = true;
     thread.start();
   }
 }
Ejemplo n.º 5
0
 synchronized void start() {
   if (queue.closed()) queue.reset();
   if (thread == null || !thread.isAlive()) {
     thread = getThreadFactory().newThread(this, "ViewHandler");
     thread.setDaemon(
         false); // thread cannot terminate if we have tasks left, e.g. when we as coord leave
     thread.start();
   }
 }
Ejemplo n.º 6
0
 synchronized void waitUntilCompleted(long timeout, boolean resume) {
   if (thread != null) {
     try {
       thread.join(timeout);
     } catch (InterruptedException e) {
       Thread.currentThread().interrupt(); // set interrupt flag again
     }
     thread = null; // Added after Brian noticed that ViewHandler leaks class loaders
   }
   if (resume) resumeForce();
 }
Ejemplo n.º 7
0
 public void stop() {
   Thread tmp;
   if (thread != null && thread.isAlive()) {
     running = false;
     tmp = thread;
     thread = null;
     closeSocket(); // this will cause the thread to break out of its loop
     tmp.interrupt();
     tmp = null;
   }
   thread = null;
 }
Ejemplo n.º 8
0
  protected void stopFlusher() {
    flushing = false;
    Thread tmp = flusher;

    while (tmp != null && tmp.isAlive()) {
      tmp.interrupt();
      ack_promise.setResult(null);
      try {
        tmp.join();
      } catch (InterruptedException e) {
      }
    }
  }
Ejemplo n.º 9
0
  protected void flush(final Address new_coord) throws InterruptedException {
    // wait until all threads currently sending messages have returned (new threads after
    // flushing=true) will block
    // flushing is set to true in startFlusher()
    while (flushing && running) {
      if (in_flight_sends.get() == 0) break;
      Thread.sleep(100);
    }

    send_lock.lockInterruptibly();
    try {
      if (log.isTraceEnabled())
        log.trace(local_addr + ": coord changed from " + coord + " to " + new_coord);
      coord = new_coord;
      is_coord = Objects.equals(local_addr, coord);
      flushMessagesInForwardTable();
    } finally {
      if (log.isTraceEnabled()) log.trace(local_addr + ": flushing completed");
      flushing = false;
      ack_mode = true; // go to ack-mode after flushing
      num_acks = 0;
      send_cond.signalAll();
      send_lock.unlock();
    }
  }
Ejemplo n.º 10
0
  /**
   * Creates a table and fills it to capacity. Then starts a number of adder threads, each trying to
   * add a seqno, blocking until there is more space. Each adder will block until the remover
   * removes elements, so the adder threads get unblocked and can then add their elements to the
   * buffer.
   */
  public void testConcurrentAddAndRemove() throws Exception {
    final int NUM = 5;
    final Table<Integer> buf = new Table<Integer>(3, 10, 0);
    for (int i = 1; i <= 10; i++) buf.add(i, i); // fill the buffer, add() will block now

    CountDownLatch latch = new CountDownLatch(1);
    Adder[] adders = new Adder[NUM];
    for (int i = 0; i < adders.length; i++) {
      adders[i] = new Adder(latch, i + 11, buf);
      adders[i].start();
    }

    System.out.println("releasing threads");
    latch.countDown();
    System.out.print("waiting for threads to be done: ");

    Thread remover =
        new Thread("Remover") {
          public void run() {
            Util.sleep(2000);
            List<Integer> list = buf.removeMany(true, 5);
            System.out.println("\nremover: removed = " + list);
          }
        };
    remover.start();

    for (Adder adder : adders) {
      try {
        adder.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

    remover.join();

    System.out.println("OK");
    System.out.println("buf = " + buf);
    assert buf.size() == 10;
    assertIndices(buf, 5, 5, 15);

    List<Integer> list = buf.removeMany(true, 0);
    System.out.println("removed = " + list);
    assert list.size() == 10;
    for (int i = 6; i <= 15; i++) assert list.contains(i);
    assertIndices(buf, 15, 15, 15);
  }
Ejemplo n.º 11
0
  /** Starts the unicast and multicast receiver threads */
  void startThreads() throws Exception {
    if (ucast_receiver == null) {
      // start the listener thread of the ucast_recv_sock
      ucast_receiver = new UcastReceiver();
      ucast_receiver.start();
      if (Trace.trace) {
        Trace.info("UDP.startThreads()", "created unicast receiver thread");
      }
    }

    if (ip_mcast) {
      if (mcast_receiver != null) {
        if (mcast_receiver.isAlive()) {
          if (Trace.trace) {
            Trace.info(
                "UDP.createThreads()",
                "did not create new multicastreceiver thread as existing "
                    + "multicast receiver thread is still running");
          }
        } else {
          mcast_receiver = null; // will be created just below...
        }
      }

      if (mcast_receiver == null) {
        mcast_receiver = new Thread(this, "UDP mcast receiver");
        mcast_receiver.setPriority(Thread.MAX_PRIORITY); // needed ????
        mcast_receiver.setDaemon(true);
        mcast_receiver.start();
      }
    }
    if (use_outgoing_packet_handler) {
      outgoing_packet_handler.start();
    }
    if (use_incoming_packet_handler) {
      incoming_packet_handler.start();
    }
  }
Ejemplo n.º 12
0
    public void run() {
      long end_time, wait_time;
      List<Request> requests = new LinkedList<Request>();
      while (Thread.currentThread().equals(thread) && !suspended) {
        try {
          boolean keepGoing = false;
          end_time = System.currentTimeMillis() + max_bundling_time;
          do {
            Request firstRequest =
                (Request)
                    queue.remove(INTERVAL); // throws a TimeoutException if it runs into timeout
            requests.add(firstRequest);
            if (!view_bundling) break;
            if (queue.size() > 0) {
              Request nextReq = (Request) queue.peek();
              keepGoing = view_bundling && firstRequest.canBeProcessedTogether(nextReq);
            } else {
              wait_time = end_time - System.currentTimeMillis();
              if (wait_time > 0)
                queue.waitUntilClosed(
                    wait_time); // misnomer: waits until element has been added or q closed
              keepGoing =
                  queue.size() > 0 && firstRequest.canBeProcessedTogether((Request) queue.peek());
            }
          } while (keepGoing && System.currentTimeMillis() < end_time);

          try {
            process(requests);
          } finally {
            requests.clear();
          }
        } catch (QueueClosedException e) {
          break;
        } catch (TimeoutException e) {
          break;
        } catch (Throwable catchall) {
          Util.sleep(50);
        }
      }
    }
Ejemplo n.º 13
0
 public synchronized void stop() {
   Thread tmp = thread;
   if (thread != null && thread.isAlive()) tmp.interrupt();
   thread = null;
 }
Ejemplo n.º 14
0
  /**
   * An event was received from the layer below. Usually the current layer will want to examine the
   * event type and - depending on its type - perform some computation (e.g. removing headers from a
   * MSG event type, or updating the internal membership list when receiving a VIEW_CHANGE event).
   * Finally the event is either a) discarded, or b) an event is sent down the stack using <code>
   * PassDown</code> or c) the event (or another event) is sent up the stack using <code>PassUp
   * </code>.
   *
   * <p>For the PING protocol, the Up operation does the following things. 1. If the event is a
   * Event.MSG then PING will inspect the message header. If the header is null, PING simply passes
   * up the event If the header is PingHeader.GET_MBRS_REQ then the PING protocol will PassDown a
   * PingRequest message If the header is PingHeader.GET_MBRS_RSP we will add the message to the
   * initial members vector and wake up any waiting threads. 2. If the event is Event.SET_LOCAL_ADDR
   * we will simple set the local address of this protocol 3. For all other messages we simple pass
   * it up to the protocol above
   *
   * @param evt - the event that has been sent from the layer below
   */
  @SuppressWarnings("unchecked")
  public Object up(Event evt) {

    switch (evt.getType()) {
      case Event.MSG:
        Message msg = (Message) evt.getArg();
        PingHeader hdr = (PingHeader) msg.getHeader(this.id);
        if (hdr == null) return up_prot.up(evt);

        PingData data = hdr.data;
        Address logical_addr = data != null ? data.getAddress() : null;

        if (is_leaving) return null; // prevents merging back a leaving member
        // (https://issues.jboss.org/browse/JGRP-1336)

        switch (hdr.type) {
          case PingHeader.GET_MBRS_REQ: // return Rsp(local_addr, coord)
            if (group_addr == null || hdr.cluster_name == null) {
              if (log.isWarnEnabled())
                log.warn(
                    "group_addr ("
                        + group_addr
                        + ") or cluster_name of header ("
                        + hdr.cluster_name
                        + ") is null; passing up discovery request from "
                        + msg.getSrc()
                        + ", but this should not"
                        + " be the case");
            } else {
              if (!group_addr.equals(hdr.cluster_name)) {
                if (log.isWarnEnabled())
                  log.warn(
                      "discarding discovery request for cluster '"
                          + hdr.cluster_name
                          + "' from "
                          + msg.getSrc()
                          + "; our cluster name is '"
                          + group_addr
                          + "'. "
                          + "Please separate your clusters cleanly.");
                return null;
              }
            }

            // add physical address and logical name of the discovery sender (if available) to the
            // cache
            if (data != null) {
              if (logical_addr == null) logical_addr = msg.getSrc();
              Collection<PhysicalAddress> physical_addrs = data.getPhysicalAddrs();
              PhysicalAddress physical_addr =
                  physical_addrs != null && !physical_addrs.isEmpty()
                      ? physical_addrs.iterator().next()
                      : null;
              if (logical_addr != null && physical_addr != null)
                down(
                    new Event(
                        Event.SET_PHYSICAL_ADDRESS,
                        new Tuple<Address, PhysicalAddress>(logical_addr, physical_addr)));
              if (logical_addr != null && data.getLogicalName() != null)
                UUID.add(logical_addr, data.getLogicalName());
              discoveryRequestReceived(msg.getSrc(), data.getLogicalName(), physical_addrs);

              synchronized (ping_responses) {
                for (Responses response : ping_responses) {
                  response.addResponse(data, false);
                }
              }
            }

            if (hdr.view_id != null) {
              // If the discovery request is merge-triggered, and the ViewId shipped with it
              // is the same as ours, we don't respond (JGRP-1315).
              ViewId my_view_id = view != null ? view.getViewId() : null;
              if (my_view_id != null && my_view_id.equals(hdr.view_id)) return null;

              boolean send_discovery_rsp =
                  force_sending_discovery_rsps
                      || is_coord
                      || current_coord == null
                      || current_coord.equals(msg.getSrc());
              if (!send_discovery_rsp) {
                if (log.isTraceEnabled())
                  log.trace(
                      local_addr
                          + ": suppressing merge response as I'm not a coordinator and the "
                          + "discovery request was not sent by a coordinator");
                return null;
              }
            }

            if (isMergeRunning()) {
              if (log.isTraceEnabled())
                log.trace(
                    local_addr + ": suppressing merge response as a merge is already in progress");
              return null;
            }

            List<PhysicalAddress> physical_addrs =
                hdr.view_id != null
                    ? null
                    : Arrays.asList(
                        (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)));
            sendDiscoveryResponse(
                local_addr,
                physical_addrs,
                is_server,
                hdr.view_id != null,
                UUID.get(local_addr),
                msg.getSrc());
            return null;

          case PingHeader.GET_MBRS_RSP: // add response to vector and notify waiting thread
            // add physical address (if available) to transport's cache
            if (data != null) {
              Address response_sender = msg.getSrc();
              if (logical_addr == null) logical_addr = msg.getSrc();
              Collection<PhysicalAddress> addrs = data.getPhysicalAddrs();
              PhysicalAddress physical_addr =
                  addrs != null && !addrs.isEmpty() ? addrs.iterator().next() : null;
              if (logical_addr != null && physical_addr != null)
                down(
                    new Event(
                        Event.SET_PHYSICAL_ADDRESS,
                        new Tuple<Address, PhysicalAddress>(logical_addr, physical_addr)));
              if (logical_addr != null && data.getLogicalName() != null)
                UUID.add(logical_addr, data.getLogicalName());

              if (log.isTraceEnabled())
                log.trace(
                    local_addr + ": received GET_MBRS_RSP from " + response_sender + ": " + data);
              boolean overwrite = logical_addr != null && logical_addr.equals(response_sender);
              synchronized (ping_responses) {
                for (Responses response : ping_responses) {
                  response.addResponse(data, overwrite);
                }
              }
            }
            return null;

          default:
            if (log.isWarnEnabled())
              log.warn("got PING header with unknown type (" + hdr.type + ')');
            return null;
        }

      case Event.GET_PHYSICAL_ADDRESS:
        try {
          sendDiscoveryRequest(group_addr, null, null);
        } catch (InterruptedIOException ie) {
          if (log.isWarnEnabled()) {
            log.warn("Discovery request for cluster " + group_addr + " interrupted");
          }
          Thread.currentThread().interrupt();
        } catch (Exception ex) {
          if (log.isErrorEnabled()) log.error("failed sending discovery request", ex);
        }
        return null;

      case Event.FIND_INITIAL_MBRS: // sent by transport
        return findInitialMembers(null);
    }

    return up_prot.up(evt);
  }
Ejemplo n.º 15
0
 public synchronized boolean isRunning() {
   return thread != null && thread.isAlive();
 }