View Javadoc
1 // 2 // Copyright 1998 CDS Networks, Inc., Medford Oregon 3 // 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. All advertising materials mentioning features or use of this software 14 // must display the following acknowledgement: 15 // This product includes software developed by CDS Networks, Inc. 16 // 4. The name of CDS Networks, Inc. may not be used to endorse or promote 17 // products derived from this software without specific prior 18 // written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND 21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 // ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE 24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 // SUCH DAMAGE. 31 // 32 33 package com.internetcds.jdbc.tds; 34 35 /*** 36 * This class provides support for canceling queries. 37 * <p> 38 * Basically all threads can be divided into two groups, workers and 39 * cancelers. The canceler can cancel at anytime, even when there is no 40 * outstanding query to cancel. A worker can be in one of 4 states- 41 * <p> 42 * 1) Not doing anything DB related.<br> 43 * 2) currently sending a request to the database. (Note- any time 44 * a request is sent to the DB the DB will send a response. This 45 * means a thread in state 2 must go to state 3.)<br> 46 * 3) waiting for a response from DB<br> 47 * 4) reading the response from DB<br> 48 * <p> 49 * I can easily make it so that only one thread at a time can be in state 50 * 2, 3, or 4. 51 * <p> 52 * The way that a cancel works in TDS is you send a cancel packet to 53 * server. The server will then stop whatever it might be doing and 54 * reply with END_OF_DATA packet with the cancel flag set. (It sends 55 * this packet even if it wasn't doing anything.) I will call this 56 * packet a CANCEL_ACK packet 57 * <p> 58 * All that I really need is to do is make sure that I try to read as 59 * many CANCEL_ACKs as I request and the I make sure that some thread is 60 * out there ready to read any CANCEL_ACKs that i request. 61 * <p> 62 * Clearly if all my worker threads are in state 1 then the cancel 63 * request could be just a nop. 64 * <p> 65 * If I have some worker thread in state 2, 3, or 4 I think I will be fine 66 * if I just make sure that the thread reads until the CANCEL_ACK packet. 67 * <p> 68 * I think I will just have a control object that has one boolean, 69 * readInProgress and two integers, cancelsRequested and 70 * cancelsProcessed. 71 * <p> 72 * <p> 73 * The doCancel() method will- 74 * a) lock the object 75 * b) if there is no read in progress it will unlock and return. 76 * c) otherwise it will send the CANCEL packet, 77 * d) increment the cancelsRequested 78 * e) unlock object and wait until notified that the 79 * cancel was ack'd 80 * <p> 81 * Whenever the worker thread wants to read a response from the DB it 82 * must- 83 * a) lock the control object,<b> 84 * b) set the queryOutstanding flag<b> 85 * c) unlock the control object<b> 86 * d) call the Tds.processSubPacket() method.<b> 87 * e) lock the control object<b> 88 * f) If the packet was a cancel ack it will increment 89 * cancelsProcessed <b> 90 * g) notify any threads that are waiting for cancel acknowledgment<b> 91 * h) unlock the control object.<b> 92 * 93 * @version $Id: CancelController.java,v 1.1 2003/04/29 18:07:50 sinisa Exp $ 94 @ @author Craig Spannring 95 */ 96 public class CancelController 97 { 98 public static final String cvsVersion = "$Id: CancelController.java,v 1.1 2003/04/29 18:07:50 sinisa Exp $"; 99 100 101 boolean awaitingData = false; 102 int cancelsRequested = 0; 103 int cancelsProcessed = 0; 104 105 public synchronized void setQueryInProgressFlag() 106 { 107 awaitingData = true; 108 } 109 110 private synchronized void clearQueryInProgressFlag() 111 { 112 awaitingData = false; 113 } 114 115 public synchronized void finishQuery( 116 boolean wasCanceled, 117 boolean moreResults) 118 { 119 // XXX Do we want to clear the query in progress flag if 120 // there are still more results for multi result set query? 121 // Whatever mechanism is used to handle outstanding query 122 // requires knowing if there is any thread out there that could 123 // still process the query acknowledgment. Prematurely clearing 124 // could cause data to be thrown out before the thread expecting 125 // the data gets a chance to process it. That could cause the 126 // thread to read some other threads query. 127 // 128 // Is it good enough to just look at the MORERESULTS bit in the 129 // TDS_END* packet and not clear the flag if we have more 130 // results? 131 if (! moreResults) 132 { 133 clearQueryInProgressFlag(); 134 } 135 136 if (wasCanceled) 137 { 138 handleCancelAck(); 139 } 140 141 // XXX Should we see if there are any more cancels pending and 142 // try to read the cancel acknowledgments? 143 } 144 145 146 public synchronized void doCancel(TdsComm comm) 147 throws java.io.IOException 148 { 149 if (awaitingData) 150 { 151 comm.startPacket(TdsComm.CANCEL); 152 comm.sendPacket(); 153 cancelsRequested++; 154 155 156 while(cancelsRequested > cancelsProcessed) 157 { 158 try 159 { 160 wait(); 161 // XXX If there are cancels pending but nobody is is 162 // awaiting data on this connection, should we go out 163 // and try to get the CANCELACK packet? 164 } 165 catch(java.lang.InterruptedException e) 166 { 167 // nop 168 } 169 } 170 } 171 else 172 { 173 // if we aren't waiting for anything from 174 // the server then we have nothing to cancel 175 176 // nop 177 } 178 } 179 180 181 182 private synchronized void handleCancelAck() 183 { 184 cancelsProcessed++; 185 notify(); 186 } 187 }

This page was automatically generated by Maven