private void sendPendingHaves() { if (destroyed) { return; } try { pending_haves_mon.enter(); int num_haves = pending_haves.size(); if (num_haves == 0) { return; } // single have -> use BT if (num_haves == 1 || az_have_version < BTMessageFactory.MESSAGE_VERSION_SUPPORTS_PADDING) { for (int i = 0; i < num_haves; i++) { Integer piece_num = (Integer) pending_haves.get(i); outgoing_message_q.addMessage(new BTHave(piece_num.intValue(), bt_have_version), true); } } else { int[] piece_numbers = new int[num_haves]; for (int i = 0; i < num_haves; i++) { piece_numbers[i] = ((Integer) pending_haves.get(i)).intValue(); } outgoing_message_q.addMessage(new AZHave(piece_numbers, az_have_version), true); } outgoing_message_q.doListenerNotifications(); pending_haves.clear(); } finally { pending_haves_mon.exit(); } }
public ByteBuffer destroy() { if (destroyed) { Debug.out("Trying to redestroy message decoder, stack trace follows: " + this); Debug.outStackTrace(); } is_paused = true; destroyed = true; // there's a concurrency issue with the decoder whereby it can be destroyed while will being // messed with. Don't // have the energy to look into it properly atm so just try to ensure that it doesn't bork too // badly (parg: 29/04/2012) // only occasional but does have potential to generate direct buffer mem leak ;( int lbuff_read = 0; int pbuff_read = 0; length_buffer.limit(SS, 4); DirectByteBuffer plb = payload_buffer; if (reading_length_mode) { lbuff_read = length_buffer.position(SS); } else { // reading payload length_buffer.position(SS, 4); lbuff_read = 4; pbuff_read = plb == null ? 0 : plb.position(SS); } ByteBuffer unused = ByteBuffer.allocate(lbuff_read + pbuff_read); // TODO convert to direct? length_buffer.flip(SS); unused.put(length_buffer.getBuffer(SS)); try { if (plb != null) { plb.flip(SS); unused.put( plb.getBuffer( SS)); // Got a buffer overflow exception here in the past - related to PEX? } } catch (RuntimeException e) { Debug.out("hit known threading issue"); } unused.flip(); length_buffer.returnToPool(); if (plb != null) { plb.returnToPool(); payload_buffer = null; } try { for (int i = 0; i < messages_last_read.size(); i++) { Message msg = (Message) messages_last_read.get(i); msg.destroy(); } } catch (RuntimeException e) { // happens if messages modified by alt thread... Debug.out("hit known threading issue"); } messages_last_read.clear(); return unused; }