|
Lines 1-5
Link Here
|
| 1 |
/********************************************************************** |
1 |
/********************************************************************** |
| 2 |
* Copyright (c) 2005, 2007 IBM Corporation and others. |
2 |
* Copyright (c) 2005, 2008 IBM Corporation and others. |
| 3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
| 4 |
* are made available under the terms of the Eclipse Public License v1.0 |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
| 5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
|
Lines 54-59
Link Here
|
| 54 |
* invocations. |
54 |
* invocations. |
| 55 |
*/ |
55 |
*/ |
| 56 |
private static ArrayList returnValueQueue = new ArrayList(); |
56 |
private static ArrayList returnValueQueue = new ArrayList(); |
|
|
57 |
|
| 58 |
/** |
| 59 |
* this list is used to keep a list of threads waiting for |
| 60 |
* return data. This way, we can wake up the proper thread |
| 61 |
* when the RMI return data becomes available |
| 62 |
* |
| 63 |
*/ |
| 64 |
private static ArrayList callDataQueue = new ArrayList(); |
| 65 |
|
| 66 |
|
| 67 |
/* |
| 68 |
* The following is used to preserve proper operation if the deprecated |
| 69 |
* return data methods are called. The boolean will stay false |
| 70 |
*/ |
| 71 |
private static boolean depracatedReturnMethodUsed = false; |
| 72 |
|
| 73 |
|
| 57 |
|
74 |
|
| 58 |
// There should be no instances of this class. |
75 |
// There should be no instances of this class. |
| 59 |
private Marshaller() throws IOException { |
76 |
private Marshaller() throws IOException { |
|
Lines 218-223
Link Here
|
| 218 |
* @return |
235 |
* @return |
| 219 |
*/ |
236 |
*/ |
| 220 |
public static byte[] marshalMethodCall(CallData callData) throws IOException { |
237 |
public static byte[] marshalMethodCall(CallData callData) throws IOException { |
|
|
238 |
|
| 239 |
synchronized (callDataQueue){ |
| 240 |
callDataQueue.add(callData); |
| 241 |
} |
| 221 |
|
242 |
|
| 222 |
// Use a custom output stream that provides pass-by-ref for remote |
243 |
// Use a custom output stream that provides pass-by-ref for remote |
| 223 |
// objects. |
244 |
// objects. |
|
Lines 372-388
Link Here
|
| 372 |
return new ReturnData(new Integer(targetId), argTypes, call, rtnVal); |
393 |
return new ReturnData(new Integer(targetId), argTypes, call, rtnVal); |
| 373 |
} |
394 |
} |
| 374 |
|
395 |
|
|
|
396 |
|
| 397 |
|
| 375 |
/** |
398 |
/** |
| 376 |
* Add the result of a method invocation to the return data queue. |
399 |
* Add the result of a method invocation to the return data queue. |
| 377 |
* |
400 |
* |
| 378 |
* @param value |
401 |
* @param value |
| 379 |
*/ |
402 |
*/ |
| 380 |
public static void queueReturnValue(ReturnData value) { |
403 |
|
|
|
404 |
public static void queueReturnValue(ReturnData returnData) { |
| 381 |
synchronized (returnValueQueue) { |
405 |
synchronized (returnValueQueue) { |
| 382 |
returnValueQueue.add(value); |
406 |
returnValueQueue.add(returnData); |
| 383 |
returnValueQueue.notifyAll(); |
407 |
if (depracatedReturnMethodUsed){ |
|
|
408 |
returnValueQueue.notifyAll(); |
| 409 |
} |
| 410 |
synchronized (callDataQueue){ |
| 411 |
int i, size = callDataQueue.size(); |
| 412 |
|
| 413 |
for (i = 0; i < size; i++){ |
| 414 |
CallData callData = (CallData)callDataQueue.get(i); |
| 415 |
if (callData.isForSameCallAs((ReturnData) returnData)){ |
| 416 |
// notify all threads (should only be one) |
| 417 |
// that are waiting for the return data. |
| 418 |
// callers are synchronized on the CallData object |
| 419 |
synchronized (callData){ |
| 420 |
callData.notifyAll(); |
| 421 |
} |
| 422 |
callDataQueue.remove(i); |
| 423 |
break; |
| 424 |
} |
| 425 |
} |
| 426 |
|
| 427 |
} |
| 428 |
|
| 384 |
} |
429 |
} |
| 385 |
} |
430 |
} |
|
|
431 |
|
| 432 |
|
| 433 |
|
| 386 |
|
434 |
|
| 387 |
/** |
435 |
/** |
| 388 |
* Pull the result of a method invocation off of the return data queue. |
436 |
* Pull the result of a method invocation off of the return data queue. |
|
Lines 432-441
Link Here
|
| 432 |
* Wait until there is data in the return queue. This method blocks the |
480 |
* Wait until there is data in the return queue. This method blocks the |
| 433 |
* calling thread until return data is present in the queue or the timeout |
481 |
* calling thread until return data is present in the queue or the timeout |
| 434 |
* occurs. |
482 |
* occurs. |
| 435 |
* @deprecated use waitForReturnDataWithTimeout so you can distinguish |
483 |
* @deprecated use waitForReturnDataWithTimeout(CallData) so you can distinguish |
| 436 |
* between return data received and timeout exceeded condition |
484 |
* between return data received and timeout exceeded condition |
| 437 |
*/ |
485 |
*/ |
| 438 |
public static void waitForReturnData() { |
486 |
public static void waitForReturnData() { |
|
|
487 |
depracatedReturnMethodUsed = true; |
| 439 |
while (!isReturnDataAvailable()) { |
488 |
while (!isReturnDataAvailable()) { |
| 440 |
try { |
489 |
try { |
| 441 |
synchronized (returnValueQueue) { |
490 |
synchronized (returnValueQueue) { |
|
Lines 453-461
Link Here
|
| 453 |
* (to allow callers to distinguish between return data received and |
502 |
* (to allow callers to distinguish between return data received and |
| 454 |
* timeout exceeded.) |
503 |
* timeout exceeded.) |
| 455 |
* @throws InterruptedException if the return data timeout is exceeded |
504 |
* @throws InterruptedException if the return data timeout is exceeded |
| 456 |
* @provisional |
505 |
* @deprecated use waitForReturnDataWithTimeout(CallData) |
|
|
506 |
* |
| 457 |
*/ |
507 |
*/ |
| 458 |
public static void waitForReturnDataWithTimeout() throws InterruptedException { |
508 |
public static void waitForReturnDataWithTimeout() throws InterruptedException { |
|
|
509 |
depracatedReturnMethodUsed = true; |
| 459 |
if (!isReturnDataAvailable()) { |
510 |
if (!isReturnDataAvailable()) { |
| 460 |
synchronized (returnValueQueue) { |
511 |
synchronized (returnValueQueue) { |
| 461 |
returnValueQueue.wait(Marshaller.WAIT_FOR_RETURN_DATA_TIMEOUT); |
512 |
returnValueQueue.wait(Marshaller.WAIT_FOR_RETURN_DATA_TIMEOUT); |
|
Lines 465-469
Link Here
|
| 465 |
} |
516 |
} |
| 466 |
} |
517 |
} |
| 467 |
|
518 |
|
|
|
519 |
/** |
| 520 |
* Wait until there is data in the return queue. This method blocks the |
| 521 |
* calling thread until return data is present in the queue or the timeout |
| 522 |
* occurs. If the timeout occurs, an InterruptedException is thrown |
| 523 |
* (to allow callers to distinguish between return data received and |
| 524 |
* timeout exceeded.) |
| 525 |
* |
| 526 |
* The difference is that this method does NOT return until the data for |
| 527 |
* the passed in CallData is actually found in the returnQueuue. The deprecated |
| 528 |
* version of this method would return even though no data was found for the caller. |
| 529 |
* |
| 530 |
* @throws InterruptedException if the return data timeout is exceeded |
| 531 |
* @provisional |
| 532 |
*/ |
| 533 |
public static ReturnData waitForReturnDataWithTimeout(CallData callData) throws InterruptedException { |
| 534 |
ReturnData returnData = getReturnData(callData); |
| 535 |
if (returnData == null){ |
| 536 |
|
| 537 |
synchronized (callData){ |
| 538 |
callData.wait(Marshaller.WAIT_FOR_RETURN_DATA_TIMEOUT); |
| 539 |
} |
| 540 |
returnData = getReturnData(callData); |
| 541 |
// if we did not get notified, that means we reached the timeout |
| 542 |
// therefore, if returnData is null, throw an exception |
| 543 |
if (returnData == null) |
| 544 |
throw new InterruptedException("Remote Method Invocation Timeout Error"); |
| 545 |
// filed bugzilla 221150 to externalize the above error string and |
| 546 |
// other hard-coded strings in hyades.execution |
| 547 |
|
| 548 |
|
| 549 |
} |
| 550 |
return returnData; |
| 551 |
} |
| 552 |
|
| 553 |
private static ReturnData getReturnData(CallData callData){ |
| 554 |
ReturnData returnData = null; |
| 555 |
synchronized (returnValueQueue){ |
| 556 |
if (isReturnDataAvailable()){ |
| 557 |
int i, size = returnValueQueue.size(); |
| 558 |
|
| 559 |
for (i = 0; i < size; i++){ |
| 560 |
if (callData.isForSameCallAs((ReturnData) returnValueQueue.get(i))){ |
| 561 |
break; |
| 562 |
} |
| 563 |
} |
| 564 |
|
| 565 |
if (i < size) |
| 566 |
returnData = (ReturnData)returnValueQueue.remove(i); |
| 567 |
} |
| 568 |
} |
| 569 |
return returnData; |
| 570 |
|
| 571 |
} |
| 468 |
|
572 |
|
| 469 |
} |
573 |
} |