Changeset 224ebb1
- Timestamp:
- Oct 9, 2008 11:58:00 AM (12 years ago)
- Branches:
- master
- Children:
- 4ec82be
- Parents:
- cb17fb8
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
apps/BOB/src/net/i2p/BOB/I2Plistener.java
rcb17fb8 r224ebb1 41 41 public class I2Plistener implements Runnable { 42 42 43 private nickname info ;43 private nickname info, database; 44 44 private Log _log; 45 45 private int tgwatch; … … 51 51 * @param S 52 52 * @param info 53 * @param database 53 54 * @param _log 54 55 */ 55 I2Plistener(I2PSocketManager S, nickname info, Log _log) { 56 I2Plistener(I2PSocketManager S, nickname info, nickname database, Log _log) { 57 this.database = database; 56 58 this.info = info; 57 59 this._log = _log; … … 63 65 /** 64 66 * Simply listen on I2P port, and thread connections 65 * 66 * @throws RuntimeException 67 * 68 * @throws RuntimeException 67 69 */ 68 70 public void run() throws RuntimeException { … … 70 72 I2PSocket sessSocket = null; 71 73 72 // needed to hack in this method :-/73 74 serverSocket.setSoTimeout(1000); 75 database.getReadLock(); 76 info.getReadLock(); 74 77 if(info.exists("INPORT")) { 75 78 tgwatch = 2; 76 79 } 77 while(info.get("RUNNING").equals(Boolean.TRUE)) { 80 info.releaseReadLock(); 81 database.releaseReadLock(); 82 boolean spin = true; 83 while(spin) { 84 85 database.getReadLock(); 86 info.getReadLock(); 87 spin = info.get("RUNNING").equals(Boolean.TRUE); 88 info.releaseReadLock(); 89 database.releaseReadLock(); 78 90 try { 79 91 try { … … 82 94 } catch(ConnectException ce) { 83 95 g = false; 84 } catch 96 } catch(SocketTimeoutException ste) { 85 97 g = false; 86 98 } … … 88 100 g = false; 89 101 // toss the connection to a new thread. 90 I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info );102 I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database); 91 103 Thread t = new Thread(conn_c, "BOBI2PtoTCP"); 92 104 t.start(); … … 94 106 95 107 } catch(I2PException e) { 96 System.out.println("Exception "+e);108 // System.out.println("Exception " + e); 97 109 } 98 110 } -
apps/BOB/src/net/i2p/BOB/I2PtoTCP.java
rcb17fb8 r224ebb1 37 37 38 38 private I2PSocket I2P; 39 private nickname info ;39 private nickname info, database; 40 40 private Socket sock; 41 41 … … 44 44 * 45 45 * @param I2Psock 46 * @param db 46 * @param info 47 * @param database 47 48 */ 48 I2PtoTCP(I2PSocket I2Psock, nickname db) {49 I2PtoTCP(I2PSocket I2Psock, nickname info, nickname database) { 49 50 this.I2P = I2Psock; 50 this.info = db; 51 this.info = info; 52 this.database = database; 51 53 } 52 54 … … 58 60 59 61 try { 60 sock = new Socket(info.get("OUTHOST").toString(), Integer.parseInt(info.get("OUTPORT").toString())); 62 database.getReadLock(); 63 info.getReadLock(); 64 String host = info.get("OUTHOST").toString(); 65 int port = Integer.parseInt(info.get("OUTPORT").toString()); 66 boolean tell = info.get("QUIET").equals(Boolean.FALSE); 67 info.releaseReadLock(); 68 database.releaseReadLock(); 69 sock = new Socket(host, port); 61 70 // make readers/writers 62 71 InputStream in = sock.getInputStream(); … … 66 75 I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default 67 76 68 if( info.get("QUIET").equals(Boolean.FALSE)) {77 if(tell) { 69 78 // tell who is connecting 70 79 out.write(I2P.getPeerDestination().toBase64().getBytes()); … … 73 82 } 74 83 // setup to cross the streams 75 TCPio conn_c = new TCPio(in, Iout, info ); // app -> I2P76 TCPio conn_a = new TCPio(Iin, out, info ); // I2P -> app84 TCPio conn_c = new TCPio(in, Iout, info, database); // app -> I2P 85 TCPio conn_a = new TCPio(Iin, out, info, database); // I2P -> app 77 86 Thread t = new Thread(conn_c, "TCPioA"); 78 87 Thread q = new Thread(conn_a, "TCPioB"); -
apps/BOB/src/net/i2p/BOB/MUXlisten.java
rcb17fb8 r224ebb1 40 40 public class MUXlisten implements Runnable { 41 41 42 private nickname info;42 private nickname database, info; 43 43 private Log _log; 44 44 private I2PSocketManager socketManager; … … 51 51 * 52 52 * @param info 53 * @param database 53 54 * @param _log 54 55 * @throws net.i2p.I2PException 55 56 * @throws java.io.IOException 56 57 */ 57 MUXlisten(nickname info, Log _log) throws I2PException, IOException { 58 MUXlisten(nickname database, nickname info, Log _log) throws I2PException, IOException { 59 this.database = database; 58 60 this.info = info; 59 61 this._log = _log; 60 this.info.add("STARTING", Boolean.TRUE);61 62 63 this.database.getReadLock(); 64 this.info.getReadLock(); 62 65 N = this.info.get("NICKNAME").toString(); 63 66 prikey = new ByteArrayInputStream((byte[])info.get("KEYS")); 64 socketManager = I2PSocketManagerFactory.createManager(prikey, (Properties)info.get("PROPERTIES")); 67 Properties Q = (Properties)info.get("PROPERTIES"); 68 this.database.releaseReadLock(); 69 this.info.releaseReadLock(); 70 71 this.database.getWriteLock(); 72 this.info.getWriteLock(); 73 this.info.add("STARTING", Boolean.TRUE); 74 this.info.releaseWriteLock(); 75 this.database.releaseWriteLock(); 76 77 socketManager = I2PSocketManagerFactory.createManager(prikey, Q); 65 78 } 66 79 … … 71 84 public void run() { 72 85 73 tg = new ThreadGroup(N); 86 this.database.getWriteLock(); 87 this.info.getWriteLock(); 74 88 info.add("RUNNING", Boolean.TRUE); 75 89 info.add("STARTING", Boolean.FALSE); 90 this.info.releaseWriteLock(); 91 this.database.releaseWriteLock(); 76 92 77 // toss the connections to a new threads. 78 // will wrap with TCP and UDP when UDP works 79 if(info.exists("OUTPORT")) { 80 // I2P -> TCP 81 I2Plistener conn = new I2Plistener(socketManager, info, _log); 82 Thread t = new Thread(tg, conn, "BOBI2Plistener " + N); 83 t.start(); 84 } 85 if(info.exists("INPORT")) { 86 // TCP -> I2P 87 TCPlistener conn = new TCPlistener(socketManager, info, _log); 88 Thread q = new Thread(tg, conn,"BOBTCPlistener" + N); 89 q.start(); 93 try { 94 tg = new ThreadGroup(N); 95 96 // toss the connections to a new threads. 97 // will wrap with TCP and UDP when UDP works 98 this.database.getReadLock(); 99 this.info.getReadLock(); 100 boolean go_out = info.exists("OUTPORT"); 101 boolean come_in = info.exists("INPORT"); 102 this.database.releaseReadLock(); 103 this.info.releaseReadLock(); 104 105 if(go_out) { 106 // I2P -> TCP 107 I2Plistener conn = new I2Plistener(socketManager, info, database, _log); 108 Thread t = new Thread(tg, conn, "BOBI2Plistener " + N); 109 t.start(); 110 } 111 112 if(come_in) { 113 // TCP -> I2P 114 TCPlistener conn = new TCPlistener(socketManager, info, database, _log); 115 Thread q = new Thread(tg, conn, "BOBTCPlistener" + N); 116 q.start(); 117 } 118 119 boolean spin = true; 120 while(spin) { 121 try { 122 Thread.sleep(1000); //sleep for 1000 ms (One second) 123 } catch(InterruptedException e) { 124 // nop 125 } 126 127 this.database.getReadLock(); 128 this.info.getReadLock(); 129 spin = info.get("STOPPING").equals(Boolean.FALSE); 130 this.database.releaseReadLock(); 131 this.info.releaseReadLock(); 132 } 133 134 this.database.getWriteLock(); 135 this.info.getWriteLock(); 136 info.add("RUNNING", Boolean.FALSE); 137 this.info.releaseWriteLock(); 138 this.database.releaseWriteLock(); 139 140 // wait for child threads and thread groups to die 141 while(tg.activeCount() + tg.activeGroupCount() != 0) { 142 try { 143 Thread.sleep(1000); //sleep for 1000 ms (One second) 144 } catch(InterruptedException ex) { 145 // nop 146 } 147 } 148 tg.destroy(); 149 // Zap reference to the ThreadGroup so the JVM can GC it. 150 tg = null; 151 } catch(Exception e) { 90 152 } 91 153 92 while(info.get("STOPPING").equals(Boolean.FALSE)) { 93 try { 94 Thread.sleep(1000); //sleep for 1000 ms (One second) 95 } catch(InterruptedException e) { 96 // nop 97 } 98 } 99 154 socketManager.destroySocketManager(); 155 // zero out everything, just incase. 156 this.database.getWriteLock(); 157 this.info.getWriteLock(); 158 info.add("STARTING", Boolean.FALSE); 159 info.add("STOPPING", Boolean.FALSE); 100 160 info.add("RUNNING", Boolean.FALSE); 101 // wait for child threads and thread groups to die 102 while (tg.activeCount() + tg.activeGroupCount() != 0) { 103 try { 104 Thread.sleep(1000); //sleep for 1000 ms (One second) 105 } catch(InterruptedException ex) { 106 // nop 107 } 108 } 109 110 socketManager.destroySocketManager(); 111 tg.destroy(); 112 // Zap reference to the ThreadGroup so the JVM can GC it. 113 tg = null; 114 info.add("STOPPING", Boolean.FALSE); 115 info.add("STARTING", Boolean.FALSE); 116 161 this.info.releaseWriteLock(); 162 this.database.releaseWriteLock(); 117 163 } 118 164 } -
apps/BOB/src/net/i2p/BOB/TCPio.java
rcb17fb8 r224ebb1 37 37 private InputStream Ain; 38 38 private OutputStream Aout; 39 private nickname info ;39 private nickname info, database; 40 40 41 41 /** … … 44 44 * @param Ain 45 45 * @param Aout 46 * @param db 46 * @param info 47 * @param database 47 48 */ 48 TCPio(InputStream Ain, OutputStream Aout, nickname db) {49 TCPio(InputStream Ain, OutputStream Aout, nickname info, nickname database) { 49 50 this.Ain = Ain; 50 51 this.Aout = Aout; 51 this.info = db; 52 this.info = info; 53 this.database = database; 52 54 } 53 55 … … 64 66 int b; 65 67 byte a[] = new byte[1]; 68 boolean spin = true; 66 69 try { 67 while(info.get("RUNNING").equals(Boolean.TRUE)) { 70 while(spin) { 71 database.getReadLock(); 72 info.getReadLock(); 73 spin = info.get("RUNNING").equals(Boolean.TRUE); 74 info.releaseReadLock(); 75 database.releaseReadLock(); 76 68 77 b = Ain.read(a, 0, 1); 69 78 // System.out.println(info.get("NICKNAME").toString() + " " + b); 70 79 if(b > 0) { 71 Aout.write(a, 0,1);72 80 Aout.write(a, 0, 1); 81 // Aout.flush(); too slow! 73 82 } else if(b == 0) { 74 83 try { … … 88 97 } 89 98 } 90 } catch( IOException e) {99 } catch(Exception e) { 91 100 } 92 101 } -
apps/BOB/src/net/i2p/BOB/TCPlistener.java
rcb17fb8 r224ebb1 42 42 public class TCPlistener implements Runnable { 43 43 44 private nickname info ;44 private nickname info, database; 45 45 private Log _log; 46 46 private int tgwatch; … … 53 53 * @param S 54 54 * @param info 55 * @param database 55 56 * @param _log 56 57 */ 57 TCPlistener(I2PSocketManager S, nickname info, Log _log) { 58 TCPlistener(I2PSocketManager S, nickname info, nickname database, Log _log) { 59 this.database = database; 58 60 this.info = info; 59 61 this._log = _log; … … 68 70 public void run() throws RuntimeException { 69 71 boolean g = false; 72 database.getReadLock(); 73 info.getReadLock(); 70 74 if(info.exists("OUTPORT")) { 71 75 tgwatch = 2; … … 76 80 Socket server = new Socket(); 77 81 listener.setSoTimeout(1000); 78 while(info.get("RUNNING").equals(Boolean.TRUE)) { 82 info.releaseReadLock(); 83 database.releaseReadLock(); 84 boolean spin = true; 85 while(spin) { 86 database.getReadLock(); 87 info.getReadLock(); 88 spin = info.get("RUNNING").equals(Boolean.TRUE); 89 info.releaseReadLock(); 90 database.releaseReadLock(); 79 91 // System.out.println("Thread count " + Thread.activeCount()); 80 92 try { … … 86 98 if(g) { 87 99 // toss the connection to a new thread. 88 TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info );100 TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database); 89 101 Thread t = new Thread(conn_c, "BOBTCPtoI2P"); 90 102 t.start(); -
apps/BOB/src/net/i2p/BOB/TCPtoI2P.java
rcb17fb8 r224ebb1 46 46 47 47 private I2PSocket I2P; 48 private nickname info ;48 private nickname info, database; 49 49 private Socket sock; 50 50 private I2PSocketManager socketManager; … … 85 85 * @param i2p 86 86 * @param socket 87 * @param db 87 * @param info 88 * @param database 88 89 */ 89 TCPtoI2P(I2PSocketManager i2p, Socket socket, nickname db) {90 TCPtoI2P(I2PSocketManager i2p, Socket socket, nickname info, nickname database) { 90 91 this.sock = socket; 91 this.info = db; 92 this.info = info; 93 this.database = database; 92 94 this.socketManager = i2p; 93 95 } … … 137 139 OutputStream Iout = I2P.getOutputStream(); 138 140 // setup to cross the streams 139 TCPio conn_c = new TCPio(in, Iout, info ); // app -> I2P140 TCPio conn_a = new TCPio(Iin, out, info ); // I2P -> app141 TCPio conn_c = new TCPio(in, Iout, info, database); // app -> I2P 142 TCPio conn_a = new TCPio(Iin, out, info, database); // I2P -> app 141 143 Thread t = new Thread(conn_c, "TCPioA"); 142 144 Thread q = new Thread(conn_a, "TCPioB"); -
apps/BOB/src/net/i2p/BOB/doCMDS.java
rcb17fb8 r224ebb1 47 47 // FIX ME 48 48 // I need a better way to do versioning, but this will do for now. 49 public static final String BMAJ = "00", BMIN = "00", BREV = "01", BEXT = "- 8";49 public static final String BMAJ = "00", BMIN = "00", BREV = "01", BEXT = "-9"; 50 50 public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT; 51 51 private Socket server; … … 154 154 } 155 155 156 private void rlock() { 157 rlock(nickinfo); 158 } 159 160 private void rlock(nickname Arg) { 161 database.getReadLock(); 162 Arg.getReadLock(); 163 } 164 165 private void runlock() { 166 runlock(nickinfo); 167 } 168 169 private void runlock(nickname Arg) { 170 Arg.releaseReadLock(); 171 database.releaseReadLock(); 172 } 173 174 private void wlock() { 175 wlock(nickinfo); 176 } 177 178 private void wlock(nickname Arg) { 179 database.getWriteLock(); 180 Arg.getWriteLock(); 181 } 182 183 private void wunlock() { 184 wunlock(nickinfo); 185 } 186 187 private void wunlock(nickname Arg) { 188 Arg.releaseWriteLock(); 189 database.releaseWriteLock(); 190 } 191 156 192 /** 157 193 * Try to print info from the database … … 162 198 */ 163 199 public void trypnt(PrintStream out, nickname info, Object key) { 164 out.print(" " + key + ": "); 165 if(info.exists(key)) { 166 out.print(info.get(key)); 167 } else { 168 out.print("not_set"); 200 rlock(info); 201 try { 202 out.print(" " + key + ": "); 203 if(info.exists(key)) { 204 out.print(info.get(key)); 205 } else { 206 out.print("not_set"); 207 } 208 } catch(Exception e) { 169 209 } 210 runlock(info); 170 211 } 171 212 … … 178 219 */ 179 220 public void tfpnt(PrintStream out, nickname info, Object key) { 180 out.print(" " + key + ": "); 181 out.print(info.exists(key)); 221 rlock(info); 222 try { 223 out.print(" " + key + ": "); 224 out.print(info.exists(key)); 225 } catch(Exception e) { 226 } 227 runlock(info); 182 228 } 183 229 … … 198 244 */ 199 245 public void nickprint(PrintStream out, nickname info) { 246 rlock(info); 200 247 trypnt(out, info, P_NICKNAME); 201 248 trypnt(out, info, P_STARTING); … … 208 255 trypnt(out, info, P_OUTPORT); 209 256 trypnt(out, info, P_OUTHOST); 210 out.println(); 211 257 try { 258 out.println(); 259 } catch(Exception e) { 260 } 261 runlock(info); 212 262 } 213 263 … … 215 265 * Print information on a specific record, indicated by nickname 216 266 * @param out 217 * @param database218 267 * @param Arg 219 268 */ 220 public void ttlpnt(PrintStream out, nickname database, Object Arg) { 269 public void ttlpnt(PrintStream out, Object Arg) { 270 database.getReadLock(); 221 271 if(database.exists(Arg)) { 222 out.print("DATA"); 272 try { 273 out.print("DATA"); 274 } catch(Exception e) { 275 } 223 276 nickprint(out, (nickname)database.get(Arg)); 224 277 } 278 database.releaseReadLock(); 225 279 } 226 280 … … 232 286 */ 233 287 public boolean tunnelactive(nickname Arg) { 234 return (Arg.get(P_STARTING).equals(Boolean.TRUE) || 288 rlock(Arg); 289 boolean retval = (Arg.get(P_STARTING).equals(Boolean.TRUE) || 235 290 Arg.get(P_STOPPING).equals(Boolean.TRUE) || 236 291 Arg.get(P_RUNNING).equals(Boolean.TRUE)); 237 292 runlock(Arg); 293 return retval; 238 294 } 239 295 … … 268 324 out.println("OK"); 269 325 while((line = in.readLine()) != null) { 270 System.gc(); // yes, this does make a huge difference...271 326 StringTokenizer token = new StringTokenizer(line, " "); // use a space as a delimiter 272 327 String Command = ""; … … 294 349 if(ns) { 295 350 if(dk) { 296 out.println("OK " + nickinfo.get(P_DEST)); 351 rlock(); 352 try { 353 out.println("OK " + nickinfo.get(P_DEST)); 354 } catch(Exception e) { 355 } 356 runlock(); 297 357 } else { 298 358 out.println("ERROR keys not set."); … … 303 363 } else if(Command.equals(C_list)) { 304 364 // Produce a formatted list of all nicknames 365 database.getReadLock(); 305 366 for(int i = 0; i < database.getcount(); i++) { 306 367 try { 307 368 info = (nickname)database.getnext(i); 308 } catch( RuntimeException b) {369 } catch(Exception b) { 309 370 break; // something bad happened. 310 371 } 311 312 out.print("DATA"); 372 try { 373 374 out.print("DATA"); 375 } catch(Exception e) { 376 } 377 info.getReadLock(); 313 378 nickprint(out, info); 314 } 379 info.releaseReadLock(); 380 } 381 database.releaseReadLock(); 315 382 out.println("OK Listing done"); 316 383 } else if(Command.equals(C_quit)) { … … 326 393 prikey = new ByteArrayOutputStream(); 327 394 d = I2PClientFactory.createClient().createDestination(prikey); 328 dk = true;395 wlock(); 329 396 nickinfo.add(P_KEYS, prikey.toByteArray()); 330 397 nickinfo.add(P_DEST, d.toBase64()); 331 // System.out.println(prikey.toByteArray().length); 332 out.println("OK " + nickinfo.get(P_DEST)); 398 dk = true; 399 wunlock(); 400 rlock(); 401 try { 402 out.println("OK " + nickinfo.get(P_DEST)); 403 } catch(Exception e) { 404 } 405 runlock(); 333 406 } catch(IOException ioe) { 334 407 BOB.error("Error generating keys" + ioe); … … 346 419 if(dk) { 347 420 prikey = new ByteArrayOutputStream(); 421 rlock(); 348 422 prikey.write(((byte[])nickinfo.get(P_KEYS))); 423 runlock(); 349 424 out.println("OK " + net.i2p.data.Base64.encode(prikey.toByteArray())); 350 425 } else { … … 356 431 out.println("ERROR tunnel is active"); 357 432 } else { 433 wlock(); 358 434 nickinfo.add(P_QUIET, new Boolean(Boolean.parseBoolean(Arg) == true)); 435 wunlock(); 359 436 out.println("OK Quiet set"); 360 437 } … … 376 453 } 377 454 if((Arg.length() == 884) && is64ok(Arg)) { 455 wlock(); 378 456 nickinfo.add(P_KEYS, prikey.toByteArray()); 379 457 nickinfo.add(P_DEST, d.toBase64()); 380 out.println("OK " + nickinfo.get(P_DEST));381 458 dk = true; 459 wunlock(); 460 rlock(); 461 try { 462 out.println("OK " + nickinfo.get(P_DEST)); 463 } catch(Exception e) { 464 } 465 runlock(); 382 466 } else { 383 467 out.println("ERROR not in BASE64 format"); … … 389 473 } else if(Command.equals(C_setnick)) { 390 474 ns = dk = ip = op = false; 475 database.getReadLock(); 391 476 try { 392 477 nickinfo = (nickname)database.get(Arg); … … 395 480 ns = true; 396 481 } 397 } catch( RuntimeException b) {482 } catch(Exception b) { 398 483 nickinfo = null; 399 484 ns = true; 400 485 } 401 486 database.releaseReadLock(); 402 487 // Clears and Sets the initial nickname structure to work with 403 488 if(ns) { 404 489 nickinfo = new nickname(); 490 wlock(); 405 491 database.add(Arg, nickinfo); 406 492 nickinfo.add(P_NICKNAME, Arg); … … 411 497 nickinfo.add(P_INHOST, "localhost"); 412 498 nickinfo.add(P_OUTHOST, "localhost"); 413 Properties Q = props;414 Q.setProperty("inbound.nickname", (String)nickinfo.get(P_NICKNAME));415 Q.setProperty("outbound.nickname", (String)nickinfo.get(P_NICKNAME));499 Properties Q = new Properties(props); 500 Q.setProperty("inbound.nickname", Arg); 501 Q.setProperty("outbound.nickname", Arg); 416 502 nickinfo.add(P_PROPERTIES, Q); 503 wunlock(); 417 504 out.println("OK Nickname set to " + Arg); 418 505 } else { … … 430 517 String pname = otoken.nextToken(); 431 518 String pval = otoken.nextToken(); 519 rlock(); 432 520 Properties Q = (Properties)nickinfo.get(P_PROPERTIES); 521 runlock(); 433 522 Q.setProperty(pname, pval); 523 wlock(); 434 524 nickinfo.add(P_PROPERTIES, Q); 525 wunlock(); 435 526 out.println("OK " + pname + " set to " + pval); 436 527 } … … 441 532 } else if(Command.equals(C_getnick)) { 442 533 // Get the nickname to work with... 534 database.getReadLock(); 443 535 try { 444 536 nickinfo = (nickname)database.get(Arg); … … 447 539 nns(out); 448 540 } 449 if(ns) { 541 database.releaseReadLock(); 542 if(ns) { 543 rlock(); 450 544 dk = nickinfo.exists(P_KEYS); 451 545 ip = nickinfo.exists(P_INPORT); 452 546 op = nickinfo.exists(P_OUTPORT); 547 runlock(); 453 548 // Finally say OK. 454 549 out.println("OK Nickname set to " + Arg); … … 462 557 } else { 463 558 int prt; 559 wlock(); 464 560 nickinfo.kill(P_INPORT); 465 561 try { … … 471 567 out.println("ERROR not a number"); 472 568 } 569 wunlock(); 570 rlock(); 473 571 ip = nickinfo.exists(P_INPORT); 572 runlock(); 474 573 if(ip) { 475 574 out.println("OK inbound port set"); … … 489 588 } else { 490 589 int prt; 590 wlock(); 491 591 nickinfo.kill(P_OUTPORT); 492 592 try { … … 498 598 out.println("ERROR not a number"); 499 599 } 600 wunlock(); 601 rlock(); 500 602 ip = nickinfo.exists(P_OUTPORT); 603 runlock(); 501 604 if(ip) { 502 605 out.println("OK outbound port set"); … … 513 616 out.println("ERROR tunnel is active"); 514 617 } else { 618 wlock(); 515 619 nickinfo.add(P_INHOST, Arg); 620 wunlock(); 516 621 out.println("OK inhost set"); 517 622 } … … 524 629 out.println("ERROR tunnel is active"); 525 630 } else { 631 wlock(); 526 632 nickinfo.add(P_OUTHOST, Arg); 633 wunlock(); 527 634 out.println("OK outhost set"); 528 635 } … … 534 641 if(ns) { 535 642 out.print("OK"); 643 rlock(); 536 644 nickprint(out, nickinfo); 645 runlock(); 537 646 } else { 538 647 nns(out); … … 546 655 MUXlisten tunnel; 547 656 try { 548 tunnel = new MUXlisten( nickinfo, _log);657 tunnel = new MUXlisten(database, nickinfo, _log); 549 658 Thread t = new Thread(tunnel); 550 nickinfo.add(P_STARTING, Boolean.TRUE);551 659 t.start(); 552 660 out.println("OK tunnel starting"); … … 563 671 // Stop the tunnel, if it is running 564 672 if(ns) { 565 if(nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE)) { 673 rlock(); 674 if(nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) { 675 runlock(); 676 wlock(); 566 677 nickinfo.add(P_STOPPING, Boolean.TRUE); 678 wunlock(); 567 679 out.println("OK tunnel stopping"); 568 680 } else { 681 runlock(); 569 682 out.println("ERROR tunnel is inactive"); 570 683 } … … 578 691 out.println("ERROR tunnel is active"); 579 692 } else { 693 database.getWriteLock(); 580 694 database.kill(nickinfo.get(P_NICKNAME)); 695 database.releaseWriteLock(); 581 696 dk = ns = ip = op = false; 582 697 out.println("OK cleared"); … … 589 704 // Show status of a nickname 590 705 out.print("OK "); 591 ttlpnt(out, database,Arg);706 ttlpnt(out, Arg); 592 707 } else { 593 708 nns(out); -
apps/BOB/src/net/i2p/BOB/nickname.java
rcb17fb8 r224ebb1 22 22 * ...for any additional details and liscense questions. 23 23 */ 24 25 24 package net.i2p.BOB; 26 25 … … 30 29 * @author sponge 31 30 */ 32 public class nickname { 33 34 private Object[][] data; 35 private int index = 0; 36 31 public class nickname { 32 33 private static final int maxWritersWaiting = 2; 34 private volatile Object[][] data; 35 private volatile int index, writersWaiting, readers; 36 private volatile boolean writingInProgress; 37 37 /** 38 38 * make initial NULL object … … 40 40 */ 41 41 public nickname() { 42 data = new Object[1][2]; 42 this.data = new Object[1][2]; 43 this.index = this.writersWaiting = this.readers = 0; 44 this.writingInProgress = false; 45 } 46 47 synchronized public void getReadLock() { 48 while(writingInProgress | (writersWaiting >= maxWritersWaiting)) { 49 try { 50 wait(); 51 } catch(InterruptedException ie) { 52 } 53 readers++; 54 } 55 } 56 57 synchronized public void releaseReadLock() { 58 readers--; 59 if((readers == 0) & (writersWaiting > 0)) { 60 notifyAll(); 61 } 62 } 63 64 synchronized public void getWriteLock() { 65 writersWaiting++; 66 while((readers > 0) | writingInProgress) { 67 try { 68 wait(); 69 } catch(InterruptedException ie) { 70 } 71 } 72 writersWaiting--; 73 writingInProgress = true; 74 } 75 76 synchronized public void releaseWriteLock() { 77 writingInProgress = false; 78 notifyAll(); 43 79 } 44 80 … … 75 111 olddata = new Object[index + 2][2]; 76 112 // copy to olddata, skipping 'k' 77 for(i = 0 , l = 0; l < index; i++, l++) {113 for(i = 0 , l = 0; l < index; i++, l++) { 78 114 if(i == k) { 79 115 l++; -
history.txt
rcb17fb8 r224ebb1 1 2008-10-09 sponge 2 * Update version to -3 3 * BOB database threadlocking fixes 4 1 5 2008-10-08 sponge 2 6 * Update version to -2 -
router/java/src/net/i2p/router/RouterVersion.java
rcb17fb8 r224ebb1 18 18 public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; 19 19 public final static String VERSION = "0.6.4"; 20 public final static long BUILD = 2;20 public final static long BUILD = 3; 21 21 public static void main(String args[]) { 22 22 System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
Note: See TracChangeset
for help on using the changeset viewer.