1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 package com.sun.star.lib.uno.protocols.urp; 21 22 import com.sun.star.bridge.InvalidProtocolChangeException; 23 import com.sun.star.bridge.ProtocolProperty; 24 import com.sun.star.bridge.XProtocolProperties; 25 import com.sun.star.lang.DisposedException; 26 import com.sun.star.lib.uno.environments.remote.IProtocol; 27 import com.sun.star.lib.uno.environments.remote.Message; 28 import com.sun.star.lib.uno.environments.remote.ThreadId; 29 import com.sun.star.lib.uno.typedesc.MethodDescription; 30 import com.sun.star.lib.uno.typedesc.TypeDescription; 31 import com.sun.star.uno.Any; 32 import com.sun.star.uno.IBridge; 33 import com.sun.star.uno.Type; 34 import com.sun.star.uno.TypeClass; 35 import com.sun.star.uno.UnoRuntime; 36 import com.sun.star.uno.XCurrentContext; 37 import java.io.DataInput; 38 import java.io.DataInputStream; 39 import java.io.DataOutputStream; 40 import java.io.IOException; 41 import java.io.InputStream; 42 import java.io.OutputStream; 43 import java.lang.reflect.Array; 44 import java.util.ArrayList; 45 import java.util.Random; 46 import java.util.StringTokenizer; 47 48 /** 49 * This class internally relies on the availability of Java UNO type information 50 * for the interface type <code>com.sun.star.bridge.XProtocolProperties</code>, 51 * even though URP itself does not rely on that type. 52 */ 53 public final class urp implements IProtocol { urp( IBridge bridge, String attributes, InputStream input, OutputStream output)54 public urp( 55 IBridge bridge, String attributes, InputStream input, 56 OutputStream output) 57 { 58 this.input = new DataInputStream(input); 59 this.output = new DataOutputStream(output); 60 marshal = new Marshal(bridge, CACHE_SIZE); 61 unmarshal = new Unmarshal(bridge, CACHE_SIZE); 62 forceSynchronous = parseAttributes(attributes); 63 } 64 65 /** 66 * 67 * @see IProtocol#init 68 */ init()69 public void init() throws IOException { 70 synchronized (monitor) { 71 if (state == STATE_INITIAL0) { 72 sendRequestChange(); 73 } 74 } 75 } 76 77 /** 78 * 79 * @see IProtocol#terminate 80 */ terminate()81 public void terminate() { 82 synchronized (monitor) { 83 state = STATE_TERMINATED; 84 initialized = true; 85 monitor.notifyAll(); 86 } 87 } 88 89 /** 90 * 91 * @see IProtocol#readMessage 92 */ readMessage()93 public Message readMessage() throws IOException { 94 for (;;) { 95 if (!unmarshal.hasMore()) { 96 unmarshal.reset(readBlock()); 97 if (!unmarshal.hasMore()) { 98 throw new IOException("closeConnection message received"); 99 } 100 } 101 UrpMessage msg; 102 int header = unmarshal.read8Bit(); 103 if ((header & HEADER_LONGHEADER) != 0) { 104 if ((header & HEADER_REQUEST) != 0) { 105 msg = readLongRequest(header); 106 } else { 107 msg = readReply(header); 108 } 109 } else { 110 msg = readShortRequest(header); 111 } 112 if (msg.isInternal()) { 113 handleInternalMessage(msg); 114 } else { 115 return msg; 116 } 117 } 118 } 119 120 /** 121 * 122 * @see IProtocol#writeRequest 123 */ writeRequest( String oid, TypeDescription type, String function, ThreadId tid, Object[] arguments)124 public boolean writeRequest( 125 String oid, TypeDescription type, String function, ThreadId tid, 126 Object[] arguments) 127 throws IOException 128 { 129 if (oid.equals(PROPERTIES_OID)) { 130 throw new IllegalArgumentException("illegal OID " + oid); 131 } 132 synchronized (monitor) { 133 while (!initialized) { 134 try { 135 monitor.wait(); 136 } catch (InterruptedException e) { 137 Thread.currentThread().interrupt(); 138 throw new RuntimeException(e); 139 } 140 } 141 if (state == STATE_TERMINATED) { 142 throw new DisposedException(); 143 } 144 return writeRequest(false, oid, type, function, tid, arguments); 145 } 146 } 147 148 /** 149 * 150 * @see IProtocol#writeReply 151 */ writeReply(boolean exception, ThreadId tid, Object result)152 public void writeReply(boolean exception, ThreadId tid, Object result) 153 throws IOException 154 { 155 synchronized (output) { 156 writeQueuedReleases(); 157 int header = HEADER_LONGHEADER; 158 PendingRequests.Item pending = pendingIn.pop(tid); 159 TypeDescription resultType; 160 TypeDescription[] argTypes; 161 Object[] args; 162 if (exception) { 163 header |= HEADER_EXCEPTION; 164 resultType = TypeDescription.getTypeDescription(TypeClass.ANY); 165 argTypes = null; 166 args = null; 167 } else { 168 resultType = pending.function.getReturnSignature(); 169 argTypes = pending.function.getOutSignature(); 170 args = pending.arguments; 171 } 172 if (!tid.equals(outL1Tid)) { 173 header |= HEADER_NEWTID; 174 outL1Tid = tid; 175 } else { 176 tid = null; 177 } 178 marshal.write8Bit(header); 179 if (tid != null) { 180 marshal.writeThreadId(tid); 181 } 182 marshal.writeValue(resultType, result); 183 if (argTypes != null) { 184 for (int i = 0; i < argTypes.length; ++i) { 185 if (argTypes[i] != null) { 186 marshal.writeValue( 187 argTypes[i].getComponentType(), 188 Array.get(args[i], 0)); 189 } 190 } 191 } 192 writeBlock(true); 193 } 194 } 195 sendRequestChange()196 private void sendRequestChange() throws IOException { 197 if (propertiesTid == null) { 198 propertiesTid = ThreadId.createFresh(); 199 } 200 random = randomGenerator.nextInt(); 201 writeRequest( 202 true, PROPERTIES_OID, 203 TypeDescription.getTypeDescription(XProtocolProperties.class), 204 PROPERTIES_FUN_REQUEST_CHANGE, propertiesTid, 205 new Object[] { Integer.valueOf(random) }); 206 state = STATE_REQUESTED; 207 } 208 handleInternalMessage(Message message)209 private void handleInternalMessage(Message message) throws IOException { 210 if (message.isRequest()) { 211 String t = message.getType().getTypeName(); 212 if (!t.equals("com.sun.star.bridge.XProtocolProperties")) { 213 throw new IOException( 214 "read URP protocol properties request with unsupported" 215 + " type " + t); 216 } 217 int fid = message.getMethod().getIndex(); 218 switch (fid) { 219 case PROPERTIES_FID_REQUEST_CHANGE: 220 checkSynchronousPropertyRequest(message); 221 synchronized (monitor) { 222 switch (state) { 223 case STATE_INITIAL0: 224 case STATE_INITIAL: 225 writeReply( 226 false, message.getThreadId(), Integer.valueOf(1)); 227 state = STATE_WAIT; 228 break; 229 case STATE_REQUESTED: 230 int n 231 = ((Integer) message.getArguments()[0]).intValue(); 232 if (random < n) { 233 writeReply( 234 false, message.getThreadId(), Integer.valueOf(1)); 235 state = STATE_WAIT; 236 } else if (random == n) { 237 writeReply( 238 false, message.getThreadId(), Integer.valueOf(-1)); 239 state = STATE_INITIAL; 240 sendRequestChange(); 241 } else { 242 writeReply( 243 false, message.getThreadId(), Integer.valueOf(0)); 244 } 245 break; 246 default: 247 writeReply( 248 true, message.getThreadId(), 249 new com.sun.star.uno.RuntimeException( 250 "read URP protocol properties requestChange" 251 + " request in illegal state")); 252 break; 253 } 254 } 255 break; 256 case PROPERTIES_FID_COMMIT_CHANGE: 257 checkSynchronousPropertyRequest(message); 258 synchronized (monitor) { 259 if (state == STATE_WAIT) { 260 ProtocolProperty[] p = (ProtocolProperty[]) 261 message.getArguments()[0]; 262 boolean ok = true; 263 boolean cc = false; 264 int i = 0; 265 for (; i < p.length; ++i) { 266 if (p[i].Name.equals(PROPERTY_CURRENT_CONTEXT)) { 267 cc = true; 268 } else { 269 ok = false; 270 break; 271 } 272 } 273 if (ok) { 274 writeReply(false, message.getThreadId(), null); 275 } else { 276 writeReply( 277 true, message.getThreadId(), 278 new InvalidProtocolChangeException( 279 "", null, p[i], 1)); 280 } 281 state = STATE_INITIAL; 282 if (!initialized) { 283 if (cc) { 284 currentContext = true; 285 initialized = true; 286 monitor.notifyAll(); 287 } else { 288 sendRequestChange(); 289 } 290 } 291 } else { 292 writeReply( 293 true, message.getThreadId(), 294 new com.sun.star.uno.RuntimeException( 295 "read URP protocol properties commitChange" 296 + " request in illegal state")); 297 } 298 } 299 break; 300 default: 301 throw new IOException( 302 "read URP protocol properties request with unsupported" 303 + " function ID " + fid); 304 } 305 } else { 306 synchronized (monitor) { 307 if (state == STATE_COMMITTED) { 308 // commitChange reply: 309 if (!message.isAbnormalTermination()) { 310 currentContext = true; 311 } 312 state = STATE_INITIAL; 313 initialized = true; 314 monitor.notifyAll(); 315 } else { 316 // requestChange reply: 317 if (message.isAbnormalTermination()) { 318 // remote side probably does not support negotiation: 319 state = STATE_INITIAL; 320 initialized = true; 321 monitor.notifyAll(); 322 } else { 323 int n = ((Integer) message.getResult()).intValue(); 324 switch (n) { 325 case -1: 326 case 0: 327 break; 328 case 1: 329 writeRequest( 330 true, PROPERTIES_OID, 331 TypeDescription.getTypeDescription( 332 XProtocolProperties.class), 333 PROPERTIES_FUN_COMMIT_CHANGE, propertiesTid, 334 new Object[] { 335 new ProtocolProperty[] { 336 new ProtocolProperty( 337 PROPERTY_CURRENT_CONTEXT, 338 Any.VOID) } }); 339 state = STATE_COMMITTED; 340 break; 341 default: 342 throw new IOException( 343 "read URP protocol properties " 344 + PROPERTIES_FUN_REQUEST_CHANGE 345 + " reply with illegal return value " + n); 346 } 347 } 348 } 349 } 350 } 351 } 352 checkSynchronousPropertyRequest(Message message)353 private void checkSynchronousPropertyRequest(Message message) 354 throws IOException 355 { 356 if (!message.isSynchronous()) { 357 throw new IOException( 358 "read URP protocol properties request for synchronous function" 359 + " marked as not SYNCHRONOUS"); 360 } 361 } 362 readBlock()363 private byte[] readBlock() throws IOException { 364 int size = input.readInt(); 365 input.readInt(); // ignore count 366 byte[] bytes = new byte[size]; 367 input.readFully(bytes); 368 return bytes; 369 } 370 readLongRequest(int header)371 private UrpMessage readLongRequest(int header) throws IOException { 372 boolean sync = false; 373 if ((header & HEADER_MOREFLAGS) != 0) { 374 if (unmarshal.read8Bit() != (HEADER_MUSTREPLY | HEADER_SYNCHRONOUS)) 375 { 376 throw new IOException( 377 "read URP request with bad MUSTREPLY/SYNCHRONOUS byte"); 378 } 379 sync = true; 380 } 381 int funId = (header & HEADER_FUNCTIONID16) != 0 382 ? unmarshal.read16Bit() : unmarshal.read8Bit(); 383 if ((header & HEADER_NEWTYPE) != 0) { 384 inL1Type = unmarshal.readType(); 385 if (inL1Type.getTypeClass() != TypeClass.INTERFACE) { 386 throw new IOException( 387 "read URP request with non-interface type " + inL1Type); 388 } 389 } 390 if ((header & HEADER_NEWOID) != 0) { 391 inL1Oid = unmarshal.readObjectId(); 392 } 393 if ((header & HEADER_NEWTID) != 0) { 394 inL1Tid = unmarshal.readThreadId(); 395 } 396 return readRequest(funId, sync); 397 } 398 readShortRequest(int header)399 private UrpMessage readShortRequest(int header) throws IOException { 400 int funId = (header & HEADER_FUNCTIONID14) != 0 401 ? ((header & HEADER_FUNCTIONID) << 8) | unmarshal.read8Bit() 402 : header & HEADER_FUNCTIONID; 403 return readRequest(funId, false); 404 } 405 readRequest(int functionId, boolean forcedSynchronous)406 private UrpMessage readRequest(int functionId, boolean forcedSynchronous) 407 throws IOException 408 { 409 boolean internal = PROPERTIES_OID.equals(inL1Oid); 410 // inL1Oid may be null in XInstanceProvider.getInstance("") 411 XCurrentContext cc = 412 (currentContext && !internal 413 && functionId != MethodDescription.ID_RELEASE) 414 ? (XCurrentContext) unmarshal.readInterface( 415 new Type(XCurrentContext.class)) 416 : null; 417 MethodDescription desc = inL1Type.getMethodDescription(functionId); 418 if (desc == null) { 419 throw new IOException( 420 "read URP request with unsupported function ID " + functionId); 421 } 422 TypeDescription[] inSig = desc.getInSignature(); 423 TypeDescription[] outSig = desc.getOutSignature(); 424 Object[] args = new Object[inSig.length]; 425 for (int i = 0; i < args.length; ++i) { 426 if (inSig[i] != null) { 427 if (outSig[i] != null) { 428 Object inout = Array.newInstance( 429 outSig[i].getComponentType().getZClass(), 1); 430 Array.set( 431 inout, 0, 432 unmarshal.readValue( 433 outSig[i].getComponentType())); 434 args[i] = inout; 435 } else { 436 args[i] = unmarshal.readValue(inSig[i]); 437 } 438 } else { 439 args[i] = Array.newInstance( 440 outSig[i].getComponentType().getZClass(), 1); 441 } 442 } 443 boolean sync = forcedSynchronous || !desc.isOneway(); 444 if (sync) { 445 pendingIn.push( 446 inL1Tid, new PendingRequests.Item(internal, desc, args)); 447 } 448 return new UrpMessage( 449 inL1Tid, true, inL1Oid, inL1Type, desc, sync, cc, false, null, args, 450 internal); 451 } 452 readReply(int header)453 private UrpMessage readReply(int header) { 454 if ((header & HEADER_NEWTID) != 0) { 455 inL1Tid = unmarshal.readThreadId(); 456 } 457 PendingRequests.Item pending = pendingOut.pop(inL1Tid); 458 TypeDescription resultType; 459 TypeDescription[] argTypes; 460 Object[] args; 461 boolean exception = (header & HEADER_EXCEPTION) != 0; 462 if (exception) { 463 resultType = TypeDescription.getTypeDescription(TypeClass.ANY); 464 argTypes = null; 465 args = null; 466 } else { 467 resultType = pending.function.getReturnSignature(); 468 argTypes = pending.function.getOutSignature(); 469 args = pending.arguments; 470 } 471 Object result = resultType == null 472 ? null : unmarshal.readValue(resultType); 473 if (argTypes != null) { 474 for (int i = 0; i < argTypes.length; ++i) { 475 if (argTypes[i] != null) { 476 Array.set( 477 args[i], 0, 478 unmarshal.readValue( 479 argTypes[i].getComponentType())); 480 } 481 } 482 } 483 return new UrpMessage( 484 inL1Tid, false, null, null, null, false, null, exception, result, 485 args, pending.internal); 486 } 487 writeRequest( boolean internal, String oid, TypeDescription type, String function, ThreadId tid, Object[] arguments)488 private boolean writeRequest( 489 boolean internal, String oid, TypeDescription type, String function, 490 ThreadId tid, Object[] arguments) 491 throws IOException 492 { 493 MethodDescription desc = type.getMethodDescription(function); 494 synchronized (output) { 495 if (desc.getIndex() == MethodDescription.ID_RELEASE 496 && releaseQueue.size() < MAX_RELEASE_QUEUE_SIZE) 497 { 498 releaseQueue.add( 499 new QueuedRelease(internal, oid, type, desc, tid)); 500 return false; 501 } else { 502 writeQueuedReleases(); 503 return writeRequest( 504 internal, oid, type, desc, tid, arguments, true); 505 } 506 } 507 } 508 writeRequest( boolean internal, String oid, TypeDescription type, MethodDescription desc, ThreadId tid, Object[] arguments, boolean flush)509 private boolean writeRequest( 510 boolean internal, String oid, TypeDescription type, 511 MethodDescription desc, ThreadId tid, Object[] arguments, 512 boolean flush) 513 throws IOException 514 { 515 int funId = desc.getIndex(); 516 if (funId < 0 || funId > MAX_FUNCTIONID16) { 517 throw new IllegalArgumentException( 518 "function ID " + funId + " out of range"); 519 } 520 boolean forceSync = forceSynchronous 521 && funId != MethodDescription.ID_RELEASE; 522 boolean moreFlags = forceSync && desc.isOneway(); 523 boolean longHeader = moreFlags; 524 int header = 0; 525 if (!type.equals(outL1Type)) { 526 longHeader = true; 527 header |= HEADER_NEWTYPE; 528 outL1Type = type; 529 } else { 530 type = null; 531 } 532 if (!oid.equals(outL1Oid)) { 533 longHeader = true; 534 header |= HEADER_NEWOID; 535 outL1Oid = oid; 536 } else { 537 oid = null; 538 } 539 if (!tid.equals(outL1Tid)) { 540 longHeader = true; 541 header |= HEADER_NEWTID; 542 outL1Tid = tid; 543 } else { 544 tid = null; 545 } 546 if (funId > MAX_FUNCTIONID14) { 547 longHeader = true; 548 } 549 if (longHeader) { 550 header |= HEADER_LONGHEADER | HEADER_REQUEST; 551 if (funId > MAX_FUNCTIONID8) { 552 header |= HEADER_FUNCTIONID16; 553 } 554 if (moreFlags) { 555 header |= HEADER_MOREFLAGS; 556 } 557 marshal.write8Bit(header); 558 if (moreFlags) { 559 marshal.write8Bit(HEADER_MUSTREPLY | HEADER_SYNCHRONOUS); 560 } 561 if (funId > MAX_FUNCTIONID8) { 562 marshal.write16Bit(funId); 563 } else { 564 marshal.write8Bit(funId); 565 } 566 if (type != null) { 567 marshal.writeType(type); 568 } 569 if (oid != null) { 570 marshal.writeObjectId(oid); 571 } 572 if (tid != null) { 573 marshal.writeThreadId(tid); 574 } 575 } else { 576 if (funId > HEADER_FUNCTIONID) { 577 marshal.write8Bit(HEADER_FUNCTIONID14 | (funId >> 8)); 578 } 579 marshal.write8Bit(funId); 580 } 581 if (currentContext && !internal 582 && funId != MethodDescription.ID_RELEASE) 583 { 584 marshal.writeInterface( 585 UnoRuntime.getCurrentContext(), 586 new Type(XCurrentContext.class)); 587 } 588 TypeDescription[] inSig = desc.getInSignature(); 589 TypeDescription[] outSig = desc.getOutSignature(); 590 for (int i = 0; i < inSig.length; ++i) { 591 if (inSig[i] != null) { 592 if (outSig[i] != null) { 593 marshal.writeValue( 594 outSig[i].getComponentType(), 595 ((Object[]) arguments[i])[0]); 596 } else { 597 marshal.writeValue( 598 inSig[i], arguments[i]); 599 } 600 } 601 } 602 boolean sync = forceSync || !desc.isOneway(); 603 if (sync) { 604 pendingOut.push( 605 outL1Tid, new PendingRequests.Item(internal, desc, arguments)); 606 } 607 writeBlock(flush); 608 return sync; 609 } 610 writeBlock(boolean flush)611 private void writeBlock(boolean flush) throws IOException { 612 byte[] data = marshal.reset(); 613 output.writeInt(data.length); 614 output.writeInt(1); 615 output.write(data); 616 if (flush) { 617 output.flush(); 618 } 619 } 620 writeQueuedReleases()621 private void writeQueuedReleases() throws IOException { 622 for (int i = releaseQueue.size(); i > 0;) { 623 --i; 624 QueuedRelease r = releaseQueue.get(i); 625 writeRequest( 626 r.internal, r.objectId, r.type, r.method, r.threadId, null, 627 false); 628 releaseQueue.remove(i); 629 } 630 } 631 parseAttributes(String attributes)632 private static boolean parseAttributes(String attributes) { 633 boolean forceSynchronous = true; 634 if (attributes != null) { 635 StringTokenizer t = new StringTokenizer(attributes, ","); 636 while (t.hasMoreTokens()) { 637 String a = t.nextToken(); 638 String v = null; 639 int i = a.indexOf('='); 640 if (i >= 0) { 641 v = a.substring(i + 1); 642 a = a.substring(0, i); 643 } 644 if (a.equalsIgnoreCase("ForceSynchronous")) { 645 forceSynchronous = parseBooleanAttributeValue(a, v); 646 } else if (a.equalsIgnoreCase("negotiate")) { 647 // Ignored: 648 parseBooleanAttributeValue(a, v); 649 } else { 650 throw new IllegalArgumentException( 651 "unknown protocol attribute " + a); 652 } 653 } 654 } 655 return forceSynchronous; 656 } 657 parseBooleanAttributeValue( String attribute, String value)658 private static boolean parseBooleanAttributeValue( 659 String attribute, String value) 660 { 661 if (value == null) { 662 throw new IllegalArgumentException( 663 "missing value for protocol attribute " + attribute); 664 } 665 if (value.equals("0")) { 666 return false; 667 } else if (value.equals("1")) { 668 return true; 669 } else { 670 throw new IllegalArgumentException( 671 "bad value " + value + " for protocol attribute " + attribute); 672 } 673 } 674 675 private static final class QueuedRelease { QueuedRelease( boolean internal, String objectId, TypeDescription type, MethodDescription method, ThreadId threadId)676 public QueuedRelease( 677 boolean internal, String objectId, TypeDescription type, 678 MethodDescription method, ThreadId threadId) 679 { 680 this.internal = internal; 681 this.objectId = objectId; 682 this.type = type; 683 this.method = method; 684 this.threadId = threadId; 685 } 686 687 public final boolean internal; 688 public final String objectId; 689 public final TypeDescription type; 690 public final MethodDescription method; 691 public final ThreadId threadId; 692 } 693 694 private static final String PROPERTIES_OID = "UrpProtocolProperties"; 695 private static final int PROPERTIES_FID_REQUEST_CHANGE = 4; 696 private static final String PROPERTIES_FUN_REQUEST_CHANGE = "requestChange"; 697 private static final int PROPERTIES_FID_COMMIT_CHANGE = 5; 698 private static final String PROPERTIES_FUN_COMMIT_CHANGE = "commitChange"; 699 private static final String PROPERTY_CURRENT_CONTEXT = "CurrentContext"; 700 701 private static final short CACHE_SIZE = 256; 702 703 private static final int HEADER_LONGHEADER = 0x80; 704 private static final int HEADER_REQUEST = 0x40; 705 private static final int HEADER_NEWTYPE = 0x20; 706 private static final int HEADER_NEWOID = 0x10; 707 private static final int HEADER_NEWTID = 0x08; 708 private static final int HEADER_FUNCTIONID16 = 0x04; 709 private static final int HEADER_MOREFLAGS = 0x01; 710 private static final int HEADER_MUSTREPLY = 0x80; 711 private static final int HEADER_SYNCHRONOUS = 0x40; 712 private static final int HEADER_FUNCTIONID14 = 0x40; 713 private static final int HEADER_FUNCTIONID = 0x3F; 714 private static final int HEADER_EXCEPTION = 0x20; 715 716 private static final int MAX_FUNCTIONID16 = 0xFFFF; 717 private static final int MAX_FUNCTIONID14 = 0x3FFF; 718 private static final int MAX_FUNCTIONID8 = 0xFF; 719 720 private static final int STATE_INITIAL0 = 0; 721 private static final int STATE_INITIAL = 1; 722 private static final int STATE_REQUESTED = 2; 723 private static final int STATE_COMMITTED = 3; 724 private static final int STATE_WAIT = 4; 725 private static final int STATE_TERMINATED = 5; 726 727 private static final int MAX_RELEASE_QUEUE_SIZE = 100; 728 729 private static final Random randomGenerator = new Random(); 730 731 private final DataInput input; 732 private final DataOutputStream output; 733 734 private final Marshal marshal; 735 private final Unmarshal unmarshal; 736 737 private final boolean forceSynchronous; 738 739 private final PendingRequests pendingIn = new PendingRequests(); 740 private final PendingRequests pendingOut = new PendingRequests(); 741 742 private final Object monitor = new Object(); 743 private int state = STATE_INITIAL0; 744 private boolean initialized = false; 745 private ThreadId propertiesTid = null; 746 private int random; 747 private boolean currentContext = false; 748 749 private ThreadId inL1Tid = null; 750 private String inL1Oid = null; 751 private TypeDescription inL1Type = null; 752 753 private ThreadId outL1Tid = null; 754 private String outL1Oid = null; 755 private TypeDescription outL1Type = null; 756 757 private final ArrayList<QueuedRelease> releaseQueue = new ArrayList<QueuedRelease>(); // of QueuedRelease 758 } 759 760 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 761