/** (synchronous version) */ public String requestWaitAndReceive(String requestData) { int recvTimeout = getRequestTimeout(); final String[] response = new String[1]; synchronized (response) { queueRequest( requestData, recvTimeout, new H1<String>() { @Override public void handle(String value) { synchronized (response) { response[0] = value; response.notify(); } } }); // wait for a while or until notified when a response is received Threads.waitOnSync(response, recvTimeout); } return response[0]; }
/** The main thread. */ private void begin() { while (!_shutdown) { // only need to set the thread state once here _threadStateHandler.handle(); try { connectAndRead(); } catch (Exception exc) { if (_shutdown) { // thread can gracefully exit return; } if (_recentlyConnected) _backoffTime = MIN_CONNETION_GAP; else { _backoffTime = Math.min(_backoffTime * 2, MAX_BACKOFF); _backoffTime = Math.max(MIN_CONNETION_GAP, _backoffTime); } long timeDiff = (System.nanoTime() - _lastSuccessfulConnection) / 1000000; if (timeDiff > _timeout) { // reset the timestamp _lastSuccessfulConnection = System.nanoTime(); _callbackHandler.handle(_timeoutCallback, _callbackErrorHandler); } _recentlyConnected = false; } Threads.wait(_lock, _backoffTime); } // (while) }
/** Synchronous version. */ public String waitAndReceive() { int recvTimeout = getRequestTimeout(); QueuedRequest request = new QueuedRequest(null, null, recvTimeout, null); synchronized (request) { queueRequest(null, _requestTimeout, null); // wait for a while or until notified when a response is received Threads.waitOnSync(request, recvTimeout); } return request.response; }
/** (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)