/** (thread entry-point) */ private void hardLinksReceiverThreadMain() { _logger.info("Instructed to use hardlinks. address:{}", _hardLinksAddresses); DatagramSocket socket = null; try { // initialise a UDP socket on an arbitrary port _hardLinksSocket = new DatagramSocket(); socket = _hardLinksSocket; while (_enabled) { DatagramPacket dp = UDPPacketRecycleQueue.instance().getReadyToUsePacket(); // ('returnPacket' will be called in 'catch' or later after use in thread-pool) try { socket.receive(dp); s_unicastInData.addAndGet(dp.getLength()); s_unicastInOps.incrementAndGet(); enqueueForProcessing(dp, s_hardLinksSocketlabel); } catch (Exception exc) { UDPPacketRecycleQueue.instance().returnPacket(dp); // ignore } } // (while) } catch (Exception exc) { _logger.warn("Failed to initialise [" + s_hardLinksSocketlabel + "] socket.", exc); } finally { _logger.info("[" + s_hardLinksSocketlabel + "] thread run to completion."); // close for good measure Stream.safeClose(socket); } }
/** Processes whatever's in the queue. */ private void processIncomingPacketQueue() { while (_enabled) { QueueEntry entry; synchronized (_incomingQueue) { if (_incomingQueue.size() <= 0) { // nothing left, so clear flag and return _isProcessingIncomingQueue = false; return; } entry = _incomingQueue.remove(); } DatagramPacket dp = entry.packet; String source = entry.source; try { // parse packet NameServicesChannelMessage message = this.parsePacket(dp); // handle message this.handleIncomingMessage(source, (InetSocketAddress) dp.getSocketAddress(), message); } catch (Exception exc) { if (!_enabled) break; // log nested exception summary instead of stack-trace dump _logger.warn( "{} while handling received packet from {}: {}", source, dp.getSocketAddress(), Exceptions.formatExceptionGraph(exc)); } finally { // make sure the packet is returned UDPPacketRecycleQueue.instance().returnPacket(entry.packet); } } // (while) }
/** (thread entry-point) */ private void unicastReceiverThreadMain() { while (_enabled) { MulticastSocket socket = null; try { synchronized (_lock) { // clear flag regardless _recycleSender = false; } socket = createMulticastSocket(s_sendSocketLabel, s_interface, 0); // make sure a recycle request hasn't since occurred synchronized (_lock) { if (_recycleSender) { Stream.safeClose(socket); continue; } _sendSocket = socket; } while (_enabled) { DatagramPacket dp = UDPPacketRecycleQueue.instance().getReadyToUsePacket(); try { socket.receive(dp); } catch (Exception exc) { UDPPacketRecycleQueue.instance().returnPacket(dp); throw exc; } if (dp.getAddress().isMulticastAddress()) { s_multicastInData.addAndGet(dp.getLength()); s_multicastInOps.incrementAndGet(); } else { s_unicastInData.addAndGet(dp.getLength()); s_unicastInOps.incrementAndGet(); } enqueueForProcessing(dp, s_sendSocketLabel); } // (inner while) } catch (Exception exc) { boolean wasClosed = (socket != null && socket.isClosed()); // clean up regardless Stream.safeClose(socket); synchronized (_lock) { if (!_enabled) break; if (wasClosed) _logger.info( s_sendSocketLabel + " was signalled to gracefully close. Will reinitialise..."); else _logger.warn(s_sendSocketLabel + " receive failed; will reinitialise...", exc); // stagger retry Threads.waitOnSync(_lock, 333); } } } // (outer while) _logger.info("This thread has run to completion."); }
/** (thread entry-point) */ private void multicastReceiverThreadMain() { while (_enabled) { MulticastSocket socket = null; try { synchronized (_lock) { // clear flag regardless _recycleReceiver = false; } socket = createMulticastSocket(s_receiveSocketlabel, s_interface, MDNS_PORT); synchronized (_lock) { // make sure not flagged since reset if (_recycleReceiver) { Stream.safeClose(socket); continue; } _receiveSocket = socket; } while (_enabled) { DatagramPacket dp = UDPPacketRecycleQueue.instance().getReadyToUsePacket(); // ('returnPacket' will be called in 'catch' or later after use in thread-pool) try { socket.receive(dp); } catch (Exception exc) { UDPPacketRecycleQueue.instance().returnPacket(dp); throw exc; } InetAddress recvAddr = dp.getAddress(); if (recvAddr.isMulticastAddress()) { s_multicastInData.addAndGet(dp.getLength()); s_multicastInOps.incrementAndGet(); } else { s_unicastInData.addAndGet(dp.getLength()); s_unicastInOps.incrementAndGet(); } // check whether it's external i.e. completely different IP address // (local multicasting would almost always be reliable) MulticastSocket otherLocal = _sendSocket; boolean isLocal = (otherLocal != null && recvAddr.equals(otherLocal.getLocalAddress())); // update counter which is used to detect silence if (!isLocal) _lastExternalMulticastPacket = System.nanoTime(); enqueueForProcessing(dp, s_receiveSocketlabel); } // (inner while) } catch (Exception exc) { // (timeouts and general IO problems) // clean up regardless Stream.safeClose(socket); synchronized (_lock) { if (!_enabled) break; if (_recycleReceiver) _logger.info(s_receiveSocketlabel + " was gracefully closed. Will reinitialise..."); else _logger.warn( s_receiveSocketlabel + " receive failed; this may be a transitional condition. Will reinitialise... message was '" + exc.toString() + "'"); // set flag _recycleSender = true; // "signal" other thread Stream.safeClose(_sendSocket); // stagger retry Threads.waitOnSync(_lock, 333); } } } // (outer while) _logger.info("This thread has run to completion."); } // (method)