LdapRequest.java 3.9 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Oracle designates this
D
duke 已提交
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Oracle in the LICENSE file that accompanied this code.
D
duke 已提交
10 11 12 13 14 15 16 17 18 19 20
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
21 22 23
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
24 25 26 27 28
 */

package com.sun.jndi.ldap;

import java.io.IOException;
29 30
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
D
duke 已提交
31
import javax.naming.CommunicationException;
32
import java.util.concurrent.TimeUnit;
D
duke 已提交
33 34 35

final class LdapRequest {

36
    private final static BerDecoder EOF = new BerDecoder(new byte[]{}, -1, 0);
D
duke 已提交
37

38 39
    LdapRequest next;   // Set/read in synchronized Connection methods
    final int msgId;          // read-only
D
duke 已提交
40

41 42 43 44 45
    private final BlockingQueue<BerDecoder> replies;
    private volatile boolean cancelled;
    private volatile boolean closed;
    private volatile boolean completed;
    private final boolean pauseAfterReceipt;
46 47

    LdapRequest(int msgId, boolean pause, int replyQueueCapacity) {
D
duke 已提交
48 49
        this.msgId = msgId;
        this.pauseAfterReceipt = pause;
50
        if (replyQueueCapacity == -1) {
51
            this.replies = new LinkedBlockingQueue<>();
52
        } else {
53
            this.replies = new LinkedBlockingQueue<>(8 * replyQueueCapacity / 10);
54
        }
D
duke 已提交
55 56
    }

57
    void cancel() {
D
duke 已提交
58
        cancelled = true;
59 60
        replies.offer(EOF);
    }
D
duke 已提交
61

62 63 64 65 66 67 68
    synchronized void close() {
        closed = true;
        replies.offer(EOF);
    }

    private boolean isClosed() {
        return closed && (replies.size() == 0 || replies.peek() == EOF);
D
duke 已提交
69 70 71
    }

    synchronized boolean addReplyBer(BerDecoder ber) {
72 73 74
        // check the closed boolean value here as we don't want anything
        // to be added to the queue after close() has been called.
        if (cancelled || closed) {
D
duke 已提交
75 76
            return false;
        }
77

D
duke 已提交
78 79 80 81 82 83 84 85 86 87
        // peek at the BER buffer to check if it is a SearchResultDone PDU
        try {
            ber.parseSeq(null);
            ber.parseInt();
            completed = (ber.peekByte() == LdapClient.LDAP_REP_RESULT);
        } catch (IOException e) {
            // ignore
        }
        ber.reset();

88 89 90 91 92
        // Add a new reply to the queue of unprocessed replies.
        try {
            replies.put(ber);
        } catch (InterruptedException e) {
            // ignore
93
        }
94

D
duke 已提交
95 96 97
        return pauseAfterReceipt;
    }

98 99 100 101 102 103 104 105 106 107 108 109 110
    BerDecoder getReplyBer(long millis) throws CommunicationException,
                                               InterruptedException {
        if (cancelled) {
            throw new CommunicationException("Request: " + msgId +
                " cancelled");
        }
        if (isClosed()) {
            return null;
        }

        BerDecoder result = millis > 0 ?
                replies.poll(millis, TimeUnit.MILLISECONDS) : replies.take();

D
duke 已提交
111 112 113 114 115
        if (cancelled) {
            throw new CommunicationException("Request: " + msgId +
                " cancelled");
        }

116
        return result == EOF ? null : result;
D
duke 已提交
117 118
    }

119
    boolean hasSearchCompleted() {
D
duke 已提交
120 121 122
        return completed;
    }
}