throw new NotConnectedException ("Not connected!");
if(pendingQuit)
throw new ClientRuntimeException("Pipeline shutting down: Quit in progess; no further requests are accepted.");
Protocol protocol = Assert.notNull(getProtocolHandler(), "thread protocol handler", ProviderException.class);
// Log.log("protocol %d@%s", protocol.hashCode(), protocol.getClass());
final boolean sendreq =
cmd.responseType != ResponseType.VIRTUAL &&
cmd.responseType != ResponseType.NOP;
/* setup send buffer if necessary */
int reqbyteslen = 0;
if(sendreq) {
reqbyteslen = ProtocolHelper.calcReqBuffSize(cmd, args);
}
/* PendingCPRequest provides transparent hook to force flush on future get(..) */
final PendingCPRequest queuedRequest = new PendingCPRequest(this, cmd);
/* possibly silly optimization, pulled out of sync block */
final OutputStream out = getOutputStream();
final boolean isflush = cmd == Command.CONN_FLUSH;
final boolean exceeds = reqbyteslen > CHUNK_BUFF_SIZE;
final boolean isquit = cmd == Command.QUIT;
/* auth is used on connector initialization and must be sent asap */
final boolean doflush =
cmd == Command.AUTH ||
cmd == Command.SELECT ||
isquit ||
isflush;
try {
requestlock.lock();
/* ======== CRITICAL BLOCK ====== */
/* 4 byte control word is [ idx | off ] */
/* chunk_ctl_word is contended and must be accessed only inside of critical block */
final int __ctl_word = ctl_word; // REVU: opportunity ..
int idx = __ctl_word >> 16;
int off = __ctl_word & 0x0000FFFF;
boolean overflows = exceeds || off + reqbyteslen > CHUNK_BUFF_SIZE ? true : false;
if(overflows) {
out.write(chunkbuff, 0, off);
out.flush();
off = 0;
pendingResponseQueue.add(chunkqueue);
chunkqueue = new PendingCPRequest[CHUNK_Q_SIZE];
idx = 0;
}
if(sendreq){
if(exceeds) {
/* can optimize and dispense with new byte[] -- only for large payloads */
/* chunkqueue should be empty and idx 0 : assert for now */
out.write(protocol.createRequestBuffer(cmd, args));
out.flush();
chunkqueue[0] = queuedRequest;
final PendingCPRequest[] oneoffitem = new PendingCPRequest[1];
oneoffitem[0] = queuedRequest;
pendingResponseQueue.add(oneoffitem);