1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 03:45:35 +02:00

[439545][dstore] potential deadlock on senders during shutdown

This commit is contained in:
Dave McKnight 2014-07-14 12:43:25 -04:00
parent c2d036c864
commit d26a0df023
2 changed files with 481 additions and 481 deletions

View file

@ -31,7 +31,7 @@
* David McKnight (IBM) - [378136] [dstore] miner.finish is stuck * David McKnight (IBM) - [378136] [dstore] miner.finish is stuck
* David McKnight (IBM) - [388472] [dstore] need alternative option for getting at server hostname * David McKnight (IBM) - [388472] [dstore] need alternative option for getting at server hostname
* David McKnight (IBM) - [390681] [dstore] need to merge differences between HEAD stream and 3.2 in ConnectionEstablisher.finished() * David McKnight (IBM) - [390681] [dstore] need to merge differences between HEAD stream and 3.2 in ConnectionEstablisher.finished()
* David McKnight (IBM) [439545][dstore] potential deadlock on senders during shutdown * David McKnight (IBM) [439545][dstore] potential deadlock on senders during shutdown
*******************************************************************************/ *******************************************************************************/
package org.eclipse.dstore.core.server; package org.eclipse.dstore.core.server;

View file

@ -1,480 +1,480 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2014 IBM Corporation and others. * Copyright (c) 2002, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Initial Contributors: * Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer * The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir, * component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
* *
* Contributors: * Contributors:
* David McKnight (IBM) [222168][dstore] Buffer in DataElement is not sent * David McKnight (IBM) [222168][dstore] Buffer in DataElement is not sent
* David McKnight (IBM) - [225507][api][breaking] RSE dstore API leaks non-API types * David McKnight (IBM) - [225507][api][breaking] RSE dstore API leaks non-API types
* David McKnight (IBM) [246826][dstore] KeepAlive does not work correctly * David McKnight (IBM) [246826][dstore] KeepAlive does not work correctly
* David McKnight (IBM) - [358301] [DSTORE] Hang during debug source look up * David McKnight (IBM) - [358301] [DSTORE] Hang during debug source look up
* David McKnight (IBM) [388873][dstore] ServerUpdateHandler _senders list should be synchronized * David McKnight (IBM) [388873][dstore] ServerUpdateHandler _senders list should be synchronized
* David McKnight (IBM) [404082][dstore] race condition on finish, removing senders * David McKnight (IBM) [404082][dstore] race condition on finish, removing senders
* David McKnight (IBM) [439545][dstore] potential deadlock on senders during shutdown * David McKnight (IBM) [439545][dstore] potential deadlock on senders during shutdown
*******************************************************************************/ *******************************************************************************/
package org.eclipse.dstore.internal.core.server; package org.eclipse.dstore.internal.core.server;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import org.eclipse.dstore.core.java.IRemoteClassInstance; import org.eclipse.dstore.core.java.IRemoteClassInstance;
import org.eclipse.dstore.core.model.DE; import org.eclipse.dstore.core.model.DE;
import org.eclipse.dstore.core.model.DataElement; import org.eclipse.dstore.core.model.DataElement;
import org.eclipse.dstore.core.model.DataStore; import org.eclipse.dstore.core.model.DataStore;
import org.eclipse.dstore.core.model.DataStoreResources; import org.eclipse.dstore.core.model.DataStoreResources;
import org.eclipse.dstore.core.model.UpdateHandler; import org.eclipse.dstore.core.model.UpdateHandler;
import org.eclipse.dstore.core.util.CommandGenerator; import org.eclipse.dstore.core.util.CommandGenerator;
import org.eclipse.dstore.internal.core.util.Sender; import org.eclipse.dstore.internal.core.util.Sender;
/** /**
* The ServerUpdateHandler is contains a queue of data update requests * The ServerUpdateHandler is contains a queue of data update requests
* and periodically transmits it's queue to the client * and periodically transmits it's queue to the client
*/ */
public class ServerUpdateHandler extends UpdateHandler public class ServerUpdateHandler extends UpdateHandler
{ {
private Sender _primarySender; // there should really only be one private Sender _primarySender; // there should really only be one
private ArrayList _senders; private ArrayList _senders;
private CommandGenerator _commandGenerator; private CommandGenerator _commandGenerator;
protected DataElement _classDocumentElement; protected DataElement _classDocumentElement;
protected DataElement _keepAliveDocumentElement; protected DataElement _keepAliveDocumentElement;
protected DataElement _confirmKeepAliveDocumentElement; protected DataElement _confirmKeepAliveDocumentElement;
protected DataElement _pendingKeepAliveRequest; protected DataElement _pendingKeepAliveRequest;
protected DataElement _pendingKeepAliveConfirmation; protected DataElement _pendingKeepAliveConfirmation;
private static String[] _keepAliveAttributes = { private static String[] _keepAliveAttributes = {
DataStoreResources.KEEPALIVE_TYPE, DataStoreResources.KEEPALIVE_TYPE,
"server.keepalive.root.id", //$NON-NLS-1$ "server.keepalive.root.id", //$NON-NLS-1$
"server.keepalive", //$NON-NLS-1$ "server.keepalive", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _confirmKeepAliveAttributes = { private static String[] _confirmKeepAliveAttributes = {
DataStoreResources.KEEPALIVECONFIRM_TYPE, DataStoreResources.KEEPALIVECONFIRM_TYPE,
"server.keepalive.confirm.root.id", //$NON-NLS-1$ "server.keepalive.confirm.root.id", //$NON-NLS-1$
"server.confirmkeepalive", //$NON-NLS-1$ "server.confirmkeepalive", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _docAttributes = { private static String[] _docAttributes = {
DataStoreResources.DOCUMENT_TYPE, DataStoreResources.DOCUMENT_TYPE,
"server.doc.root.id", //$NON-NLS-1$ "server.doc.root.id", //$NON-NLS-1$
"server.document", //$NON-NLS-1$ "server.document", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _fileAttributes = { private static String[] _fileAttributes = {
DataStoreResources.FILE_TYPE, DataStoreResources.FILE_TYPE,
"server.file.root.id", //$NON-NLS-1$ "server.file.root.id", //$NON-NLS-1$
"server.file", //$NON-NLS-1$ "server.file", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _classAttributes = { private static String[] _classAttributes = {
DataStoreResources.CLASS_TYPE, DataStoreResources.CLASS_TYPE,
"server.class.root.id", //$NON-NLS-1$ "server.class.root.id", //$NON-NLS-1$
"server.class", //$NON-NLS-1$ "server.class", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _requestClassAttributes = { private static String[] _requestClassAttributes = {
DataStoreResources.REQUEST_CLASS_TYPE, DataStoreResources.REQUEST_CLASS_TYPE,
"server.requestclass.root.id", //$NON-NLS-1$ "server.requestclass.root.id", //$NON-NLS-1$
"server.requestclass", //$NON-NLS-1$ "server.requestclass", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
private static String[] _serializeAttributes = { private static String[] _serializeAttributes = {
DataStoreResources.SERIALIZED_TYPE, DataStoreResources.SERIALIZED_TYPE,
"server.serialized.root.id", //$NON-NLS-1$ "server.serialized.root.id", //$NON-NLS-1$
"server.serialized", //$NON-NLS-1$ "server.serialized", //$NON-NLS-1$
"doc", //$NON-NLS-1$ "doc", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
"", //$NON-NLS-1$ "", //$NON-NLS-1$
DataStoreResources.FALSE, DataStoreResources.FALSE,
"2"}; //$NON-NLS-1$ "2"}; //$NON-NLS-1$
protected DataElement _fileDocumentElement; protected DataElement _fileDocumentElement;
protected DataElement _docDocumentElement; protected DataElement _docDocumentElement;
protected DataElement _requestClassDocumentElement; protected DataElement _requestClassDocumentElement;
protected DataElement _serializedDocumentElement; protected DataElement _serializedDocumentElement;
/** /**
* Constructor * Constructor
*/ */
public ServerUpdateHandler() public ServerUpdateHandler()
{ {
_senders = new ArrayList(); _senders = new ArrayList();
_commandGenerator = new CommandGenerator(); _commandGenerator = new CommandGenerator();
} }
/** /**
* Sets the associated DataStore * Sets the associated DataStore
*/ */
public void setDataStore(DataStore dataStore) public void setDataStore(DataStore dataStore)
{ {
super.setDataStore(dataStore); super.setDataStore(dataStore);
_commandGenerator.setDataStore(dataStore); _commandGenerator.setDataStore(dataStore);
_fileDocumentElement = dataStore.createTransientObject(_fileAttributes); _fileDocumentElement = dataStore.createTransientObject(_fileAttributes);
_docDocumentElement = dataStore.createObject(null, _docAttributes); _docDocumentElement = dataStore.createObject(null, _docAttributes);
_requestClassDocumentElement = dataStore.createTransientObject(_requestClassAttributes); _requestClassDocumentElement = dataStore.createTransientObject(_requestClassAttributes);
_serializedDocumentElement = dataStore.createTransientObject(_serializeAttributes); _serializedDocumentElement = dataStore.createTransientObject(_serializeAttributes);
_classDocumentElement = dataStore.createTransientObject(_classAttributes); _classDocumentElement = dataStore.createTransientObject(_classAttributes);
_keepAliveDocumentElement = dataStore.createTransientObject(_keepAliveAttributes); _keepAliveDocumentElement = dataStore.createTransientObject(_keepAliveAttributes);
_confirmKeepAliveDocumentElement = dataStore.createTransientObject(_confirmKeepAliveAttributes); _confirmKeepAliveDocumentElement = dataStore.createTransientObject(_confirmKeepAliveAttributes);
} }
/** /**
* Add a sender to the list of senders. Normally there is only one * Add a sender to the list of senders. Normally there is only one
* client for the server, which requires one <code>Sender</code>. If * client for the server, which requires one <code>Sender</code>. If
* there are more than one clients, then this is how senders are added. * there are more than one clients, then this is how senders are added.
* *
* @param sender a sender connected to a socket * @param sender a sender connected to a socket
*/ */
public void addSender(Sender sender) public void addSender(Sender sender)
{ {
synchronized(_senders){ synchronized(_senders){
_senders.add(sender); _senders.add(sender);
} }
_primarySender = sender; _primarySender = sender;
} }
/** /**
* Remove a sender from the list of senders. * Remove a sender from the list of senders.
* @param sender the sender to remove * @param sender the sender to remove
*/ */
public void removeSender(Sender sender) public void removeSender(Sender sender)
{ {
synchronized (_senders){ synchronized (_senders){
_senders.remove(sender); _senders.remove(sender);
} }
if (sender == _primarySender){ if (sender == _primarySender){
_primarySender = null; _primarySender = null;
} }
if (_senders.size() == 0) if (_senders.size() == 0)
{ {
finish(); finish();
} }
} }
/** /**
* Sends bytes to the specified file on the client. * Sends bytes to the specified file on the client.
* *
* @param path the name of the file on the client * @param path the name of the file on the client
* @param bytes the bytes to send * @param bytes the bytes to send
* @param size the number of bytes to send * @param size the number of bytes to send
* @param binary indicates whether to send the bytes and binary or text * @param binary indicates whether to send the bytes and binary or text
*/ */
public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary) public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary)
{ {
updateFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER); updateFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
} }
/** /**
* Sends bytes to the specified file on the client. * Sends bytes to the specified file on the client.
* *
* @param path the name of the file on the client * @param path the name of the file on the client
* @param bytes the bytes to send * @param bytes the bytes to send
* @param size the number of bytes to send * @param size the number of bytes to send
* @param binary indicates whether to send the bytes and binary or text * @param binary indicates whether to send the bytes and binary or text
* @param byteStreamHandlerId indicates the byte stream handler to receive the bytes * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes
* *
*/ */
public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) public synchronized void updateFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
{ {
//DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path); //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path);
DataElement document = _fileDocumentElement; DataElement document = _fileDocumentElement;
document.setAttribute(DE.A_NAME, byteStreamHandlerId); document.setAttribute(DE.A_NAME, byteStreamHandlerId);
document.setAttribute(DE.A_VALUE, byteStreamHandlerId); document.setAttribute(DE.A_VALUE, byteStreamHandlerId);
document.setAttribute(DE.A_SOURCE, path); document.setAttribute(DE.A_SOURCE, path);
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setParent(null); document.setParent(null);
_primarySender.sendFile(document, bytes, size, binary); _primarySender.sendFile(document, bytes, size, binary);
} }
/** /**
* Appends bytes to the specified file on the client. * Appends bytes to the specified file on the client.
* *
* @param path the name of the file on the client * @param path the name of the file on the client
* @param bytes the bytes to send * @param bytes the bytes to send
* @param size the number of bytes to send * @param size the number of bytes to send
* @param binary indicates whether to send the bytes and binary or text * @param binary indicates whether to send the bytes and binary or text
*/ */
public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary) public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary)
{ {
updateAppendFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER); updateAppendFile(path, bytes, size, binary, DataStoreResources.DEFAULT_BYTESTREAMHANDLER);
} }
/** /**
* Appends bytes to the specified file on the client. * Appends bytes to the specified file on the client.
* *
* @param path the name of the file on the client * @param path the name of the file on the client
* @param bytes the bytes to send * @param bytes the bytes to send
* @param size the number of bytes to send * @param size the number of bytes to send
* @param binary indicates whether to send the bytes and binary or text * @param binary indicates whether to send the bytes and binary or text
* @param byteStreamHandlerId indicates the byte stream handler to receive the bytes * @param byteStreamHandlerId indicates the byte stream handler to receive the bytes
*/ */
public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId) public synchronized void updateAppendFile(String path, byte[] bytes, int size, boolean binary, String byteStreamHandlerId)
{ {
//DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path); //DataElement document = _dataStore.createObject(null, DataStoreResources.FILE_TYPE, byteStreamHandlerId, path, path);
DataElement document = _fileDocumentElement; DataElement document = _fileDocumentElement;
document.setAttribute(DE.A_NAME, byteStreamHandlerId); document.setAttribute(DE.A_NAME, byteStreamHandlerId);
document.setAttribute(DE.A_VALUE, byteStreamHandlerId); document.setAttribute(DE.A_VALUE, byteStreamHandlerId);
document.setAttribute(DE.A_SOURCE, path); document.setAttribute(DE.A_SOURCE, path);
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setParent(null); document.setParent(null);
_primarySender.sendAppendFile(document, bytes, size, binary); _primarySender.sendAppendFile(document, bytes, size, binary);
} }
/** /**
* Periodically called on the handler thread to sends data updates. * Periodically called on the handler thread to sends data updates.
*/ */
public void handle() public void handle()
{ {
if (!_dataObjects.isEmpty() || _pendingKeepAliveConfirmation != null || _pendingKeepAliveRequest != null || !_classesToSend.isEmpty()) if (!_dataObjects.isEmpty() || _pendingKeepAliveConfirmation != null || _pendingKeepAliveRequest != null || !_classesToSend.isEmpty())
{ {
try { try {
sendUpdates(); sendUpdates();
} }
catch (OutOfMemoryError e){ catch (OutOfMemoryError e){
System.exit(-1); System.exit(-1);
} }
} }
} }
/** /**
* Periodically called to send data in the queue from the server to the client * Periodically called to send data in the queue from the server to the client
*/ */
public void sendUpdates() public void sendUpdates()
{ {
synchronized (_dataObjects) synchronized (_dataObjects)
{ {
//DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "server.doc"); //DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "server.doc");
DataElement document = _docDocumentElement; DataElement document = _docDocumentElement;
document.removeNestedData(); document.removeNestedData();
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setUpdated(true); document.setUpdated(true);
document.setParent(null); document.setParent(null);
_commandGenerator.generateResponse(document, _dataObjects); _commandGenerator.generateResponse(document, _dataObjects);
_primarySender.sendDocument(document, 20); _primarySender.sendDocument(document, 20);
if (_pendingKeepAliveConfirmation != null) if (_pendingKeepAliveConfirmation != null)
{ {
_primarySender.sendKeepAliveConfirmation(_pendingKeepAliveConfirmation); _primarySender.sendKeepAliveConfirmation(_pendingKeepAliveConfirmation);
_pendingKeepAliveConfirmation = null; _pendingKeepAliveConfirmation = null;
} }
if (_pendingKeepAliveRequest != null) if (_pendingKeepAliveRequest != null)
{ {
_primarySender.sendKeepAliveRequest(_pendingKeepAliveRequest); _primarySender.sendKeepAliveRequest(_pendingKeepAliveRequest);
_pendingKeepAliveRequest = null; _pendingKeepAliveRequest = null;
} }
for (int i = 0; i < _dataObjects.size(); i++) for (int i = 0; i < _dataObjects.size(); i++)
{ {
DataElement obj = (DataElement) _dataObjects.get(i); DataElement obj = (DataElement) _dataObjects.get(i);
clean(obj); clean(obj);
} }
_dataObjects.clear(); _dataObjects.clear();
//_dataStore.getLogRoot().removeNestedData(); //_dataStore.getLogRoot().removeNestedData();
//_dataStore.getTempRoot().removeNestedData(); //_dataStore.getTempRoot().removeNestedData();
} }
// finished sending updates, now send all classes that are waiting // finished sending updates, now send all classes that are waiting
// in the queue // in the queue
while (_classesToSend.size() > 0) while (_classesToSend.size() > 0)
{ {
DataElement document = null; DataElement document = null;
synchronized (_classesToSend) synchronized (_classesToSend)
{ {
document = (DataElement)_classesToSend.remove(0); document = (DataElement)_classesToSend.remove(0);
synchronized (_senders){ synchronized (_senders){
for (int i = 0; i < _senders.size(); i++) for (int i = 0; i < _senders.size(); i++)
{ {
Sender sender = (Sender) _senders.get(i); Sender sender = (Sender) _senders.get(i);
sender.sendClass(document); sender.sendClass(document);
} }
} }
} }
} }
} }
/** /**
* Removes the sender that is associated with the specified socket. This causes * Removes the sender that is associated with the specified socket. This causes
* A disconnect for the client that is associated with this socket. * A disconnect for the client that is associated with this socket.
* *
* @param socket the socket on which a sender communicates * @param socket the socket on which a sender communicates
*/ */
public void removeSenderWith(Socket socket) public void removeSenderWith(Socket socket)
{ {
for (int i = 0; i < _senders.size(); i++) for (int i = 0; i < _senders.size(); i++)
{ {
Sender sender = (Sender) _senders.get(i); Sender sender = (Sender) _senders.get(i);
if (sender.socket() == socket) if (sender.socket() == socket)
{ {
// sender sends last ack before death // sender sends last ack before death
DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "exit", "exit"); //$NON-NLS-1$ //$NON-NLS-2$ DataElement document = _dataStore.createObject(null, DataStoreResources.DOCUMENT_TYPE, "exit", "exit"); //$NON-NLS-1$ //$NON-NLS-2$
sender.sendDocument(document, 2); sender.sendDocument(document, 2);
removeSender(sender); removeSender(sender);
} }
} }
if (_primarySender != null && _primarySender.socket() == socket){ if (_primarySender != null && _primarySender.socket() == socket){
_primarySender = null; _primarySender = null;
} }
} }
/** /**
* Implemented to provide the means by which classes are sent * Implemented to provide the means by which classes are sent
* across the comm channel. * across the comm channel.
* @param className the name of the class to request * @param className the name of the class to request
*/ */
public synchronized void requestClass(String className) public synchronized void requestClass(String className)
{ {
DataElement document = _requestClassDocumentElement; DataElement document = _requestClassDocumentElement;
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setAttribute(DE.A_NAME, className); document.setAttribute(DE.A_NAME, className);
document.setAttribute(DE.A_VALUE, className); document.setAttribute(DE.A_VALUE, className);
document.setParent(null); document.setParent(null);
//DataElement document = _dataStore.createObject(null, DataStoreResources.REQUEST_CLASS_TYPE, className); //DataElement document = _dataStore.createObject(null, DataStoreResources.REQUEST_CLASS_TYPE, className);
_primarySender.requestClass(document); _primarySender.requestClass(document);
} }
public synchronized void updateClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId) public synchronized void updateClassInstance(IRemoteClassInstance runnable, String deserializebyteStreamHandlerId)
{ {
DataElement document = _serializedDocumentElement; DataElement document = _serializedDocumentElement;
document.setAttribute(DE.A_NAME, runnable.toString()); document.setAttribute(DE.A_NAME, runnable.toString());
document.setAttribute(DE.A_SOURCE, deserializebyteStreamHandlerId); document.setAttribute(DE.A_SOURCE, deserializebyteStreamHandlerId);
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setParent(null); document.setParent(null);
_primarySender.sendRemoteClassRunnable(document, runnable); _primarySender.sendRemoteClassRunnable(document, runnable);
notifyInput(); notifyInput();
} }
/** /**
* Implemented to provide the means by which classes are sent * Implemented to provide the means by which classes are sent
* across the comm channel. * across the comm channel.
* @param className the name of the class to send * @param className the name of the class to send
* @param classByteStreamHandlerId the name of the byte stream handler to use to receive the class * @param classByteStreamHandlerId the name of the byte stream handler to use to receive the class
*/ */
public synchronized void sendClass(String className, String classByteStreamHandlerId) public synchronized void sendClass(String className, String classByteStreamHandlerId)
{ {
// send pending updates before sending class // send pending updates before sending class
if (_dataObjects.size() > 0) if (_dataObjects.size() > 0)
sendUpdates(); sendUpdates();
DataElement document = _classDocumentElement; DataElement document = _classDocumentElement;
document.setAttribute(DE.A_NAME, className); document.setAttribute(DE.A_NAME, className);
document.setAttribute(DE.A_SOURCE, classByteStreamHandlerId); document.setAttribute(DE.A_SOURCE, classByteStreamHandlerId);
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setParent(null); document.setParent(null);
addClassToSend(document); addClassToSend(document);
} }
/** /**
* Adds a class to the queue of classes (represented by DataElements) to * Adds a class to the queue of classes (represented by DataElements) to
* be sent to the client. * be sent to the client.
* @param classElement the DataElement representing the class to be sent * @param classElement the DataElement representing the class to be sent
*/ */
public void addClassToSend(DataElement classElement) public void addClassToSend(DataElement classElement)
{ {
synchronized (_classesToSend) synchronized (_classesToSend)
{ {
if (!_classesToSend.contains(classElement)) if (!_classesToSend.contains(classElement))
{ {
_classesToSend.add(classElement); _classesToSend.add(classElement);
} }
} }
} }
/** /**
* Implemented to provide the means by which classes are requested and sent * Implemented to provide the means by which classes are requested and sent
* across the comm channel. * across the comm channel.
* @param className the name of the class to send * @param className the name of the class to send
*/ */
public synchronized void sendClass(String className) public synchronized void sendClass(String className)
{ {
sendClass(className, "default"); //$NON-NLS-1$ sendClass(className, "default"); //$NON-NLS-1$
} }
public void sendKeepAliveRequest() public void sendKeepAliveRequest()
{ {
DataElement document = _keepAliveDocumentElement; DataElement document = _keepAliveDocumentElement;
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setAttribute(DE.A_NAME, "request"); //$NON-NLS-1$ document.setAttribute(DE.A_NAME, "request"); //$NON-NLS-1$
document.setAttribute(DE.A_VALUE, "request"); //$NON-NLS-1$ document.setAttribute(DE.A_VALUE, "request"); //$NON-NLS-1$
document.setParent(null); document.setParent(null);
_pendingKeepAliveRequest = document; _pendingKeepAliveRequest = document;
handle(); // bypassing threading handle(); // bypassing threading
} }
public void sendKeepAliveConfirmation() public void sendKeepAliveConfirmation()
{ {
DataElement document = _confirmKeepAliveDocumentElement; DataElement document = _confirmKeepAliveDocumentElement;
document.setPendingTransfer(true); document.setPendingTransfer(true);
document.setAttribute(DE.A_NAME, "confirm"); //$NON-NLS-1$ document.setAttribute(DE.A_NAME, "confirm"); //$NON-NLS-1$
document.setAttribute(DE.A_VALUE, "confirm"); //$NON-NLS-1$ document.setAttribute(DE.A_VALUE, "confirm"); //$NON-NLS-1$
document.setParent(null); document.setParent(null);
_pendingKeepAliveConfirmation = document; _pendingKeepAliveConfirmation = document;
handle(); // bypassing threading handle(); // bypassing threading
} }
public synchronized void waitForInput() public synchronized void waitForInput()
{ {
if (_dataObjects.size() == 0 && _classesToSend.size() == 0 && _pendingKeepAliveConfirmation == null && _pendingKeepAliveRequest == null) if (_dataObjects.size() == 0 && _classesToSend.size() == 0 && _pendingKeepAliveConfirmation == null && _pendingKeepAliveRequest == null)
{ {
super.waitForInput(); super.waitForInput();
} }
} }
/** /**
* Indicates whether the xml generator should transfer the buffer attribute of a DataElement * Indicates whether the xml generator should transfer the buffer attribute of a DataElement
* @param flag true to transfer the buffer attribute * @param flag true to transfer the buffer attribute
*/ */
public void setGenerateBuffer(boolean flag) public void setGenerateBuffer(boolean flag)
{ {
_primarySender.setGenerateBuffer(flag); _primarySender.setGenerateBuffer(flag);
} }
} }